home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / term / term_47a_pch.lha / Source / term-4.7a / Main.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  99KB  |  5,196 lines

  1. /*
  2. **    Main.c
  3. **
  4. **    Program main routines and event loop
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Argument vectors offsets. */
  17.  
  18. enum    {
  19.             ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
  20.             ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,ARG_LANGUAGE,ARG_PHONEBOOK,ARG_AUTODIAL,
  21.             ARG_AUTOEXIT,ARG_WINDOWTITLE,
  22.  
  23.             ARG_COUNT
  24.         };
  25.  
  26.     /* The shell argument template and the corresponding help message. */
  27.  
  28. STATIC STRPTR         ArgTemplate =    "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,"
  29.                                     "SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,"
  30.                                     "QUIET/S,BEHIND/S,DEBUG/S,LANGUAGE/K,PHONEBOOK/K,"
  31.                                     "AUTODIAL/S,AUTOEXIT/S,WINDOWTITLE/K";
  32.  
  33. STATIC STRPTR        ArgHelp =        "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
  34.                                     "            [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
  35.                                     "            [NEW] [SYNC] [QUIET] [BEHIND] [LANGUAGE <Name>] [PHONEBOOK <File name>]\n"
  36.                                     "            [AUTODIAL] [AUTOEXIT] [WINDOWTITLE <Title>]\n"
  37.                                     "\n"
  38.                                     "      Window = Output window specifier\n"
  39.                                     "   PubScreen = Name of public screen to open window upon\n"
  40.                                     "     Startup = ARexx script file to run on startup\n"
  41.                                     "    Settings = Main configuration file name or path name to search for it\n"
  42.                                     "        Unit = Serial device driver unit number\n"
  43.                                     "      Device = Serial device driver name\n"
  44.                                     "         New = Spawn a new `term' process\n"
  45.                                     "        Sync = Keep links to Shell environment\n"
  46.                                     "       Quiet = Start iconified\n"
  47.                                     "      Behind = Open screen behind all other screens, don't activate the window\n"
  48.                                     "   Phonebook = Name of phonebook file to load\n"
  49.                                     "    Autodial = Dial phonebook entries which are marked for autodialing\n"
  50.                                     "    Autoexit = Exit `term' after dialing all autodial entries\n"
  51.                                     " Windowtitle = Display this text as the terminal window title\n"
  52.                                     "    Language = Language to use for the user interface\n\n";
  53.  
  54.     /* Local config path variable. */
  55.  
  56. STATIC STRPTR        ConfigPath;
  57. STATIC UBYTE        ThePath[MAX_FILENAME_LENGTH];
  58.  
  59.     /* Startup file name. */
  60.  
  61. STATIC UBYTE        StartupFile[MAX_FILENAME_LENGTH];
  62.  
  63.     /* Console output window specifier. */
  64.  
  65. STATIC UBYTE        WindowName[256];
  66.  
  67.     /* Did we hang up the line? */
  68.  
  69. STATIC BOOL            HungUp;
  70.  
  71.     /* Go on redialing? */
  72.  
  73. STATIC BOOL            KeepRedialing;
  74. STATIC BOOL            AutoDial;
  75. STATIC BOOL            AutoExit;
  76.  
  77.     /* Display the connection cost? */
  78.  
  79. STATIC BOOL            DisplayHangup;
  80. STATIC ULONG        DisplayPay;
  81.  
  82.     /* Poll OwnDevUnit.library for the device to become available again? */
  83.  
  84. STATIC BOOL            PollODU;
  85. STATIC UWORD        PollODUCount;
  86.  
  87.     /* Check the menu for items to dial? */
  88.  
  89. STATIC BOOL            CheckDialMenu;
  90.  
  91.     /* Local routines */
  92.  
  93. STATIC BOOL HandleInput(VOID);
  94. STATIC VOID ClearDialMenu(VOID);
  95. STATIC BOOL DialMenuToDialList(VOID);
  96. STATIC VOID HandleMenu(ULONG Code,ULONG Qualifier);
  97. STATIC VOID HandleIconify(VOID);
  98. STATIC VOID HandleOnlineCleanup(BOOL Hangup);
  99. STATIC VOID HandleFlowChange(VOID);
  100. STATIC VOID FullHangup(BOOL ForceIt);
  101. STATIC BOOL AskDial(struct Window *Parent);
  102. STATIC VOID GoOnline(VOID);
  103. STATIC VOID ReadyToDial(struct DataDialMsg *DialMsg);
  104. STATIC VOID HandleUpload(UBYTE Type);
  105. STATIC VOID LocalReleaseSerial(VOID);
  106. STATIC VOID HandleKeyboardInput(UBYTE Char,UWORD Code,ULONG Qualifier,STRPTR InputBuffer,LONG Len);
  107.  
  108.     /* Main():
  109.      *
  110.      *    This is our main entry point.
  111.      */
  112.  
  113. LONG
  114. Main()
  115. {
  116.     LONG Error = 0;
  117.  
  118.         /* Are we running as a child of Workbench? */
  119.  
  120.     ThisProcess = (struct Process *)FindTask(NULL);
  121.  
  122.     if(ThisProcess->pr_CLI)
  123.         WBenchMsg = NULL;
  124.     else
  125.     {
  126.         WaitPort(&ThisProcess->pr_MsgPort);
  127.  
  128.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess->pr_MsgPort);
  129.     }
  130.  
  131.         /* Now try to open dos.library and utility.library and
  132.          * proceed to examine the startup parameters.
  133.          */
  134.  
  135.     DOSBase        = (struct DosLibrary *)OpenLibrary("dos.library",0);
  136.     UtilityBase    = OpenLibrary("utility.library",0);
  137.  
  138.     if(DOSBase && UtilityBase)
  139.     {
  140.         struct RDArgs *ArgsPtr;
  141.         STRPTR *ArgArray;
  142.         BOOL LaunchNew;
  143.  
  144.             /* Reset these first. */
  145.  
  146.         ArgsPtr        = NULL;
  147.         ArgArray    = NULL;
  148.         LaunchNew    = TRUE;
  149.  
  150.             /* We were called from Shell. */
  151.  
  152.         if(ThisProcess->pr_CLI)
  153.         {
  154.                 /* No home directory to return to. */
  155.  
  156.             WBenchLock = NULL;
  157.  
  158.                 /* Use the ReadArgs parser, allocate the
  159.                  * argument vectors...
  160.                  */
  161.  
  162.             if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  163.             {
  164.                 if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  165.                 {
  166.                     ArgsPtr->RDA_ExtHelp = ArgHelp;
  167.  
  168.                         /* Parse the args (if any). */
  169.  
  170.                     if(ReadArgs(ArgTemplate,(LONG *)ArgArray,ArgsPtr))
  171.                     {
  172.                             /* Pop a running `term' to the front? */
  173.  
  174.                         if(!ArgArray[ARG_NEW])
  175.                             LaunchNew = FALSE;
  176.  
  177.                             /* For debugging purposes; not used yet. */
  178.  
  179.                         if(ArgArray[ARG_DEBUG])
  180.                             DebugFlag = TRUE;
  181.  
  182.                             /* Special language requested? */
  183.  
  184.                         if(ArgArray[ARG_LANGUAGE])
  185.                             LimitedStrcpy(sizeof(Language),Language,ArgArray[ARG_LANGUAGE]);
  186.  
  187.                             /* Are we to use a special settings path? */
  188.  
  189.                         if(ArgArray[ARG_SETTINGS])
  190.                         {
  191.                             ConfigPath = ThePath;
  192.  
  193.                             LimitedStrcpy(sizeof(ThePath),ThePath,ArgArray[ARG_SETTINGS]);
  194.                         }
  195.  
  196.                             /* Are we to use a special ARexx host port name? */
  197.  
  198.                         if(ArgArray[ARG_PORTNAME])
  199.                             LimitedStrcpy(sizeof(RexxPortName),RexxPortName,ArgArray[ARG_PORTNAME]);
  200.  
  201.                             /* Are we to use a special output window name? */
  202.  
  203.                         if(ArgArray[ARG_WINDOW])
  204.                             LimitedStrcpy(sizeof(WindowName),WindowName,ArgArray[ARG_WINDOW]);
  205.  
  206.                             /* Are we to run an ARexx script on startup? */
  207.  
  208.                         if(ArgArray[ARG_STARTUP])
  209.                             LimitedStrcpy(sizeof(StartupFile),StartupFile,ArgArray[ARG_STARTUP]);
  210.  
  211.                             /* Load a special phonebook file */
  212.  
  213.                         if(ArgArray[ARG_PHONEBOOK])
  214.                             LimitedStrcpy(sizeof(LastPhone),LastPhone,ArgArray[ARG_PHONEBOOK]);
  215.  
  216.                         if(ArgArray[ARG_AUTODIAL])
  217.                             AutoDial = TRUE;
  218.  
  219.                         if(ArgArray[ARG_AUTOEXIT])
  220.                             AutoExit = TRUE;
  221.  
  222.                             /* Are we to open a window on a public screen? */
  223.  
  224.                         if(ArgArray[ARG_PUBSCREEN])
  225.                             LimitedStrcpy(sizeof(SomePubScreenName),SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
  226.  
  227.                             /* Are we to use a special device? */
  228.  
  229.                         if(ArgArray[ARG_DEVICE])
  230.                         {
  231.                             LimitedStrcpy(sizeof(NewDevice),NewDevice,ArgArray[ARG_DEVICE]);
  232.  
  233.                             UseNewDevice = TRUE;
  234.                         }
  235.  
  236.                             /* Are we to use a special unit number? */
  237.  
  238.                         if(ArgArray[ARG_UNIT])
  239.                         {
  240.                             NewUnit = *(LONG *)ArgArray[ARG_UNIT];
  241.  
  242.                             UseNewUnit = TRUE;
  243.                         }
  244.  
  245.                             /* Are we to start up iconified? */
  246.  
  247.                         if(ArgArray[ARG_QUIET])
  248.                         {
  249.                             if(!StartupFile[0])
  250.                                 DoIconify = TRUE;
  251.                         }
  252.  
  253.                             /* Hide the screen and don't activate the window? */
  254.  
  255.                         if(ArgArray[ARG_BEHIND])
  256.                             KeepQuiet = TRUE;
  257.  
  258.                             /* Use a special window title? */
  259.  
  260.                         if(ArgArray[ARG_WINDOWTITLE])
  261.                         {
  262.                             CopyMem(ArgArray[ARG_WINDOWTITLE],WindowTitle,79);
  263.                             WindowTitle[79] = 0;
  264.                         }
  265.                         else
  266.                             WindowTitle[0] = 0;
  267.                     }
  268.                     else
  269.                         Error = IoErr();
  270.                 }
  271.                 else
  272.                     Error = IoErr();
  273.             }
  274.             else
  275.                 Error = IoErr();
  276.         }
  277.         else
  278.         {
  279.             BOOL ScrewThePath = TRUE;
  280.  
  281.                 /* Change to the program's home directory. */
  282.  
  283.             WBenchLock = CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
  284.  
  285.                 /* Open icon.library, we want to take a
  286.                  * look at the icon.
  287.                  */
  288.  
  289.             if(IconBase = OpenLibrary("icon.library",0))
  290.             {
  291.                 struct DiskObject *Icon;
  292.  
  293.                     /* Try to read the icon file. */
  294.  
  295.                 if(Icon = GetProgramIcon())
  296.                 {
  297.                     STRPTR Type;
  298.  
  299.                     if(FindToolType((UBYTE **)Icon->do_ToolTypes,"DEBUG"))
  300.                         DebugFlag = TRUE;
  301.  
  302.                     if(FindToolType((UBYTE **)Icon->do_ToolTypes,"NOPATHFIX"))
  303.                         ScrewThePath = FALSE;
  304.  
  305.                         /* Look for a `Language' tooltype. */
  306.  
  307.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"LANGUAGE"))
  308.                         LimitedStrcpy(sizeof(Language),Language,Type);
  309.  
  310.                         /* Look for a `Settings' tooltype. */
  311.  
  312.                     if(ConfigPath = FindToolType((UBYTE **)Icon->do_ToolTypes,"SETTINGS"))
  313.                     {
  314.                             /* Remember the path and continue. */
  315.  
  316.                         LimitedStrcpy(sizeof(ThePath),ThePath,ConfigPath);
  317.  
  318.                         ConfigPath = ThePath;
  319.                     }
  320.  
  321.                         /* Look for a `Phonebook' tooltype. */
  322.  
  323.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"PHONEBOOK"))
  324.                         LimitedStrcpy(sizeof(LastPhone),LastPhone,Type);
  325.  
  326.                     if(FindToolType((UBYTE **)Icon->do_ToolTypes,"AUTODIAL"))
  327.                         AutoDial = TRUE;
  328.  
  329.                     if(FindToolType((UBYTE **)Icon->do_ToolTypes,"AUTOEXIT"))
  330.                         AutoExit = TRUE;
  331.  
  332.                         /* Look for a `Portname' tooltype. */
  333.  
  334.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"PORTNAME"))
  335.                         LimitedStrcpy(sizeof(RexxPortName),RexxPortName,Type);
  336.                     else
  337.                         RexxPortName[0] = 0;
  338.  
  339.                         /* Look for a `Window' tooltype. */
  340.  
  341.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"WINDOW"))
  342.                         LimitedStrcpy(sizeof(WindowName),WindowName,Type);
  343.  
  344.                         /* Look for a `Windowtitle' tooltype. */
  345.  
  346.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"WINDOWTITLE"))
  347.                         LimitedStrcpy(sizeof(WindowTitle),WindowTitle,Type);
  348.                     else
  349.                         WindowTitle[0] = 0;
  350.  
  351.                         /* Look for a `Pubscreen' tooltype. */
  352.  
  353.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"PUBSCREEN"))
  354.                         LimitedStrcpy(sizeof(SomePubScreenName),SomePubScreenName,Type);
  355.                     else
  356.                         SomePubScreenName[0] = 0;
  357.  
  358.                         /* Look for a `Startup' tooltype. */
  359.  
  360.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"STARTUP"))
  361.                         LimitedStrcpy(sizeof(StartupFile),StartupFile,Type);
  362.                     else
  363.                         StartupFile[0] = 0;
  364.  
  365.                         /* Look for a `Device' tooltype. */
  366.  
  367.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"DEVICE"))
  368.                     {
  369.                         if(Type[0])
  370.                         {
  371.                             LimitedStrcpy(sizeof(NewDevice),NewDevice,Type);
  372.  
  373.                             UseNewDevice = TRUE;
  374.                         }
  375.                     }
  376.  
  377.                         /* Look for a `Unit' tooltype. */
  378.  
  379.                     if(Type = FindToolType((UBYTE **)Icon->do_ToolTypes,"UNIT"))
  380.                     {
  381.                         if(Type[0])
  382.                         {
  383.                             NewUnit = Atol(Type);
  384.  
  385.                             UseNewUnit = TRUE;
  386.                         }
  387.                     }
  388.  
  389.                         /* Look for a `Quiet' tooltype. */
  390.  
  391.                     if(FindToolType((UBYTE **)Icon->do_ToolTypes,"QUIET"))
  392.                     {
  393.                         if(!StartupFile[0])
  394.                             DoIconify = TRUE;
  395.                     }
  396.  
  397.                         /* Look for a `Behind' tooltype. */
  398.  
  399.                     if(FindToolType((UBYTE **)Icon->do_ToolTypes,"BEHIND"))
  400.                         KeepQuiet = TRUE;
  401.  
  402.                         /* Free the icon. */
  403.  
  404.                     FreeDiskObject(Icon);
  405.                 }
  406.  
  407.                 CloseLibrary(IconBase);
  408.                 IconBase = NULL;
  409.             }
  410.  
  411.                 /* Try to create a local CLI structure so
  412.                  * Shell commands will receive a valid
  413.                  * search path list.
  414.                  */
  415.  
  416.             if(ScrewThePath)
  417.                 AttachCLI(WBenchMsg);
  418.         }
  419.  
  420.             /* Show the error message; Error can be non-zero only if
  421.              * `term' was started from shell.
  422.              */
  423.  
  424.         if(Error)
  425.             PrintFault(Error,"term");
  426.         else
  427.         {
  428.                 /* If there is already a `term' program running, pop its window to the front. */
  429.  
  430.             if(!LaunchNew)
  431.             {
  432.                 struct TermPort *TermPort;
  433.  
  434.                     /* If no other program is running, don't bother. */
  435.  
  436.                 Forbid();
  437.  
  438.                 if(!(TermPort = TermPort = (struct TermPort *)FindPort(TERMPORTNAME)))
  439.                     LaunchNew = TRUE;
  440.                 else
  441.                 {
  442.                         /* Open intuition and pop the window to the front. */
  443.  
  444.                     if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  445.                     {
  446.                         if(TermPort->TopWindow)
  447.                             BumpWindow(TermPort->TopWindow);
  448.  
  449.                         CloseLibrary((struct Library *)IntuitionBase);
  450.                         IntuitionBase = NULL;
  451.                     }
  452.                 }
  453.  
  454.                 Permit();
  455.             }
  456.  
  457.                 /* Do something sensible? */
  458.  
  459.             if(LaunchNew)
  460.             {
  461.                 BYTE OldTaskPri = ThisProcess->pr_Task.tc_Node.ln_Pri;
  462.  
  463.                 if(StackSize(NULL) < 16384)
  464.                 {
  465.                     LONG Success;
  466.  
  467.                     if(!StackCall(&Success,16384,0,(STACKCALL)HandleInput))
  468.                         Error = ERROR_NO_FREE_STORE;
  469.                 }
  470.                 else
  471.                 {
  472.                     if(!HandleInput())
  473.                         Error = ERROR_NO_FREE_STORE;
  474.                 }
  475.  
  476.                 CloseAll();
  477.  
  478.                 SetTaskPri((struct Task *)ThisProcess,OldTaskPri);
  479.             }
  480.         }
  481.  
  482.             /* Now clean up any allocated data. */
  483.  
  484.         if(ArgsPtr)
  485.         {
  486.             FreeArgs(ArgsPtr);
  487.             FreeDosObject(DOS_RDARGS,ArgsPtr);
  488.         }
  489.  
  490.         FreeVec(ArgArray);
  491.  
  492.             /* Return to the old drawer. */
  493.  
  494.         if(WBenchMsg)
  495.             CurrentDir(WBenchLock);
  496.     }
  497.  
  498.         /* Close the libraries. */
  499.  
  500.     CloseLibrary((struct Library *)DOSBase);
  501.     CloseLibrary(UtilityBase);
  502.  
  503.         /* If run from Workbench, return the startup message. */
  504.  
  505.     if(WBenchMsg)
  506.     {
  507.         Forbid();
  508.  
  509.         ReplyMsg((struct Message *)WBenchMsg);
  510.     }
  511.  
  512.     if(Error)
  513.         return(RETURN_ERROR);
  514.     else
  515.         return(RETURN_OK);
  516. }
  517.  
  518. #ifdef BETA
  519. STRPTR Warning =
  520.     "\f  Just to make sure you know what you are using:\r\n"
  521.     "\r\n"
  522.     "     \033#6This really is a\r\n"
  523.     "        \033[5m\033#3BETA TEST\r\n"
  524.     "        \033#4BETA TEST\033[0m\r\n"
  525.     "         \033#6release!\r\n"
  526.     "\033#5\r\n"
  527.     "                   \033[4mDISCLAIMER:\033[0m\r\n"
  528.     "\r\n"
  529.     "This  product  is  meant  for educational purposes\r\n"
  530.     "only.   If   condition   persists,   consult  your\r\n"
  531.     "physician.  Edited  for  television. See label for\r\n"
  532.     "sequence.  Avoid  contact  with  skin. No purchase\r\n"
  533.     "necessary.  Use  only in well-ventilated area. Not\r\n"
  534.     "recommended  for  children.  No  anchovies  unless\r\n"
  535.     "otherwise  specified.  Driver does not carry cash.\r\n"
  536.     "This supersedes all previous notices.\r\n";
  537. #endif    /* BETA */
  538.  
  539.     /* HandleInput():
  540.      *
  541.      *    This is our main input loop (check window & serial).
  542.      */
  543.  
  544. STATIC BOOL
  545. HandleInput()
  546. {
  547.     STRPTR             Result;
  548.     SENDLINE         OriginalSendLine;
  549.     PhonebookHandle    *PhoneHandle;
  550.  
  551.     ThisProcess = (struct Process *)FindTask(NULL);
  552.  
  553.         /* Open the resources we need. */
  554.  
  555.     if(Result = OpenAll(ConfigPath))
  556.     {
  557.         if(IntuitionBase && Result[0])
  558.             ShowRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  559.  
  560.         return(FALSE);
  561.     }
  562.  
  563.         /* Store the output window name. */
  564.  
  565.     if(WindowName[0])
  566.         LimitedStrcpy(sizeof(Config->MiscConfig->WindowName),Config->MiscConfig->WindowName,WindowName);
  567.  
  568.         /* Tell the user what he probably doesn't know yet. */
  569.  
  570.     if(TermVersion > Config->SerialConfig->LastVersionSaved || (TermVersion == Config->SerialConfig->LastVersionSaved && TermRevision > Config->SerialConfig->LastRevisionSaved))
  571.     {
  572.         BlockWindows();
  573.  
  574.         ScreenToFront(Window->WScreen);
  575.  
  576.         DisplayBeep(Window->WScreen);
  577.         DisplayBeep(Window->WScreen);
  578.  
  579.         ShowInfo(Window,LocaleString(MSG_ATTENTION_PLEASE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_REMINDER_TXT));
  580.  
  581.         ReleaseWindows();
  582.     }
  583.  
  584.         /* Give a hint. */
  585.  
  586.     if(Config->MiscConfig->ProtectiveMode && !FirstInvocation)
  587.     {
  588.         BlockWindows();
  589.  
  590.         if(Config->SerialConfig->BaudRate >= 4800 && Config->SerialConfig->HandshakingProtocol == HANDSHAKING_NONE && !Config->SerialConfig->DirectConnection)
  591.         {
  592.             ScreenToFront(Window->WScreen);
  593.  
  594.             if(ShowRequest(Window,LocaleString(MSG_NO_RTSCTS_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Config->SerialConfig->BaudRate))
  595.             {
  596.                 SaveConfig(Config,PrivateConfig);
  597.  
  598.                 Config->SerialConfig->HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
  599.  
  600.                 ConfigSetup();
  601.             }
  602.         }
  603.  
  604.         if(Config->SerialConfig->BaudRate >= 4800 && Config->ModemConfig->ConnectAutoBaud)
  605.         {
  606.             ScreenToFront(Window->WScreen);
  607.  
  608.             if(ShowRequest(Window,LocaleString(MSG_AUTOBAUD_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  609.             {
  610.                 SaveConfig(Config,PrivateConfig);
  611.  
  612.                 Config->ModemConfig->ConnectAutoBaud = FALSE;
  613.  
  614.                 ConfigSetup();
  615.             }
  616.         }
  617.  
  618.         ReleaseWindows();
  619.     }
  620.  
  621.         /* Don't confuse the user yet, do it later ;-) */
  622.  
  623.     FirstInvocation = FALSE;
  624.  
  625.         /* Start the online timer if a carrier is present? */
  626.  
  627.     if(Config->SerialConfig->CheckCarrier && !Config->SerialConfig->DirectConnection)
  628.     {
  629.             /* Is the carrier signal present? */
  630.  
  631.         if(!(GetSerialStatus() & CIAF_COMCD))
  632.             GoOnline();
  633.     }
  634.  
  635.         /* Start up iconified? */
  636.  
  637.     if(DoIconify)
  638.     {
  639.         HandleIconify();
  640.  
  641.         DoIconify = FALSE;
  642.     }
  643.  
  644.         /* If we came out of iconified mode, check if were told to quit. */
  645.  
  646.     if(!MainTerminated)
  647.     {
  648.         if(!KeepQuiet)
  649.             BumpWindow(Window);
  650.  
  651.             /* Set up the public screen data. */
  652.  
  653.         PubScreenStuff();
  654.  
  655.             /* Change program priority. */
  656.  
  657.         SetTaskPri((struct Task *)ThisProcess,(LONG)Config->MiscConfig->Priority);
  658.  
  659.         BlockWindows();
  660.  
  661.             /* Load the phone book. */
  662.  
  663.         if(PhoneHandle = LoadPhonebook(LastPhone))
  664.         {
  665.             DeletePhonebook(GlobalPhoneHandle);
  666.             GlobalPhoneHandle = PhoneHandle;
  667.  
  668.             strcpy(Config->PhonebookFileName,LastPhone);
  669.         }
  670.  
  671.             /* Build new menu strip. */
  672.  
  673.         if(!AttachMenu(NULL))
  674.         {
  675.             if(IntuitionBase)
  676.                 ShowRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMINIT_FAILED_TO_CREATE_MENUS_TXT));
  677.  
  678.             return(FALSE);
  679.         }
  680.         else
  681.         {
  682.             if(Online)
  683.                 SetDialMenu(FALSE);
  684.         }
  685.  
  686.             /* Show our business card. */
  687.  
  688.         if(!StartupFile[0] && !Config->CommandConfig->StartupMacro[0] && !KeepQuiet && !(GlobalPhoneHandle->AutoDial || AutoDial))
  689.             ShowAbout(TRUE);
  690.  
  691.         ReleaseWindows();
  692.  
  693.             /* Don't do anything silly. */
  694.  
  695.         KeepQuiet = FALSE;
  696.  
  697.         LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  698.  
  699.             /* Initialize the modem. */
  700.  
  701.         OriginalSendLine = ChangeSendLine(SendLineDial);
  702.  
  703.         SerialCommand(Config->ModemConfig->ModemInit);
  704.  
  705.             /* Execute the startup macro (if any). */
  706.  
  707.         if(Config->CommandConfig->StartupMacro[0])
  708.             SerialCommand(Config->CommandConfig->StartupMacro);
  709.  
  710.         RestoreSendLine(SendLineDial,OriginalSendLine);
  711.  
  712.         #ifdef BETA
  713.         ConProcess(Warning,strlen(Warning));
  714.         #endif    /* BETA */
  715.  
  716.             /* Check if we should dial some entries from the phonebook */
  717.             /* right upon startup */
  718.  
  719.         if(GlobalPhoneHandle->AutoDial || AutoDial)
  720.         {
  721.             PhoneEntry **Phonebook;
  722.             BOOL DidSomething;
  723.             LONG i;
  724.  
  725.             Phonebook = GlobalPhoneHandle->Phonebook;
  726.             DidSomething = FALSE;
  727.  
  728.             for(i = 0 ; i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  729.             {
  730.                 if(Phonebook[i]->Header->AutoDial && GlobalPhoneHandle->Phonebook[i]->Header->Number[0])
  731.                 {
  732.                     MarkDialEntry(GlobalPhoneHandle,Phonebook[i]);
  733.  
  734.                     DidSomething = TRUE;
  735.                 }
  736.             }
  737.  
  738.             if(DidSomething)
  739.             {
  740.                 if(AddAllDialEntries(GlobalPhoneHandle))
  741.                 {
  742.                     DoDial = DIAL_LIST;
  743.  
  744.                     if(GlobalPhoneHandle->AutoExit || AutoExit)
  745.                         KeepRedialing = TRUE;
  746.                 }
  747.             }
  748.         }
  749.         else
  750.         {
  751.             PhoneEntry **Phonebook;
  752.             LONG HowMany;
  753.             LONG i;
  754.  
  755.             Phonebook = GlobalPhoneHandle->Phonebook;
  756.             HowMany = 0;
  757.  
  758.             for(i = 0 ; i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  759.             {
  760.                 if(Phonebook[i]->Header->Marked > 0)
  761.                     HowMany++;
  762.             }
  763.  
  764.             if(HowMany > 0)
  765.             {
  766.                 LONG j,Counter,Which;
  767.  
  768.                 for(j = 0 ; j < HowMany ; j++)
  769.                 {
  770.                     Counter    = Which = -1;
  771.  
  772.                     for(i = 0 ; i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  773.                     {
  774.                         if(Phonebook[i]->Header->Marked > 0)
  775.                         {
  776.                             if(Counter == -1 || Phonebook[i]->Header->Marked <= Counter)
  777.                             {
  778.                                 Counter    = Phonebook[i]->Header->Marked;
  779.                                 Which    = i;
  780.                             }
  781.                         }
  782.                     }
  783.  
  784.                     if(Which != -1)
  785.                     {
  786.                         MarkDialEntry(GlobalPhoneHandle,Phonebook[Which]);
  787.                         Phonebook[Which]->Header->Marked = 0;
  788.                     }
  789.                 }
  790.  
  791.                 AddAllDialEntries(GlobalPhoneHandle);
  792.             }
  793.         }
  794.  
  795.             /* Process the startup file if any. */
  796.  
  797.         if(StartupFile[0])
  798.             ActivateJob(MainJobQueue,StartupFileJob);
  799.  
  800.             /* Go into input loop... */
  801.  
  802.         do
  803.         {
  804.                 /* Dial the list */
  805.  
  806.             if(DoDial != DIAL_IGNORE)
  807.             {
  808.                 DoDial = DIAL_IGNORE;
  809.  
  810.                 if(Online && !IsListEmpty(&RexxDialMsgList))
  811.                     DispatchRexxDialMsgList(FALSE);
  812.                 else
  813.                 {
  814.                     BlockWindows();
  815.  
  816.                     ClearDialMenu();
  817.  
  818.                     do
  819.                     {
  820.                         if(!DialPanel(GlobalPhoneHandle))
  821.                         {
  822.                             KeepRedialing = FALSE;
  823.                             break;
  824.                         }
  825.                     }
  826.                     while(PhonePanel(NULL));
  827.  
  828.                     if(!GlobalPhoneHandle->AutoExit)
  829.                         KeepRedialing = FALSE;
  830.  
  831.                     SetRedialMenu();
  832.  
  833.                     ReleaseWindows();
  834.                 }
  835.             }
  836.  
  837.                 /* Process the job queue. */
  838.  
  839.             ProcessJobQueue(MainJobQueue);
  840.  
  841.                 /* Is that it? */
  842.  
  843.             if(MainTerminated)
  844.             {
  845.                 LONG Complaint;
  846.  
  847.                     /* Check if there are ARexx programs running in the background. */
  848.  
  849.                 if(GetLaunchCounter() > 0)
  850.                     Complaint = MSG_TERMMAIN_CANNOT_QUIT_YET_TXT;
  851.                 else
  852.                 {
  853.                         /* If we are about to quit, try to close the screen. */
  854.  
  855.                     if(!DeleteDisplay())
  856.                         Complaint = MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT;
  857.                     else
  858.                         Complaint = 0;
  859.                 }
  860.  
  861.                     /* Check if we must complain. */
  862.  
  863.                 if(Complaint > 0)
  864.                 {
  865.                     BlockWindows();
  866.                     ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(Complaint));
  867.                     ReleaseWindows();
  868.  
  869.                     MainTerminated = FALSE;
  870.                 }
  871.             }
  872.             else
  873.             {
  874.                     /* Make the user notice not too obvious events. */
  875.  
  876.                 if(FlowInfo.Changed)
  877.                     HandleFlowChange();
  878.             }
  879.         }
  880.         while(!MainTerminated);
  881.     }
  882.  
  883.         /* Send the modem exit command. */
  884.  
  885.     SendLine = (SENDLINE)SendLineDial;
  886.     SerialCommand(Config->ModemConfig->ModemExit);
  887.  
  888.         /* Stop I/O processing. */
  889.  
  890.     ClearSerial();
  891.  
  892.         /* Say goodbye. */
  893.  
  894.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  895.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  896.  
  897.     return(TRUE);
  898. }
  899.  
  900.     /* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF):
  901.      *
  902.      *    Transmit text the user typed or pasted via the
  903.      *    clipboard.
  904.      */
  905.  
  906. VOID
  907. SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF)
  908. {
  909.     LONG Mask;
  910.     UBYTE c;
  911.  
  912.     if(Config->SerialConfig->StripBit8)
  913.         Mask = 0x7F;
  914.     else
  915.         Mask = 0xFF;
  916.  
  917.     while(Len--)
  918.     {
  919.         switch(CharType[c = (*Buffer++) & Mask])
  920.         {
  921.             case CHAR_ENTER:
  922.  
  923.                 if(Get_xOFF())
  924.                 {
  925.                     if(Bell)
  926.                         BellSignal();
  927.                 }
  928.                 else
  929.                 {
  930.                     if(ConvertLF)
  931.                     {
  932.                         switch(Config->TerminalConfig->SendCR)
  933.                         {
  934.                             case EOL_LF:
  935.  
  936.                                 SerWrite("\n",1);
  937.                                 break;
  938.  
  939.                             case EOL_CR:
  940.  
  941.                                 SerWrite("\r",1);
  942.                                 break;
  943.  
  944.                             case EOL_LFCR:
  945.  
  946.                                 SerWrite("\n\r",2);
  947.                                 break;
  948.  
  949.                             case EOL_CRLF:
  950.  
  951.                                 SerWrite("\r\n",2);
  952.                                 break;
  953.                         }
  954.                     }
  955.                     else
  956.                     {
  957.                         switch(Config->TerminalConfig->SendLF)
  958.                         {
  959.                             case EOL_LF:
  960.  
  961.                                 SerWrite("\n",1);
  962.                                 break;
  963.  
  964.                             case EOL_CR:
  965.  
  966.                                 SerWrite("\r",1);
  967.                                 break;
  968.  
  969.                             case EOL_LFCR:
  970.  
  971.                                 SerWrite("\n\r",2);
  972.                                 break;
  973.  
  974.                             case EOL_CRLF:
  975.  
  976.                                 SerWrite("\r\n",2);
  977.                                 break;
  978.                         }
  979.                     }
  980.                 }
  981.  
  982.                 break;
  983.  
  984.             case CHAR_RETURN:
  985.  
  986.                 if(Get_xOFF())
  987.                 {
  988.                     if(Bell)
  989.                         BellSignal();
  990.                 }
  991.                 else
  992.                 {
  993.                     switch(Config->TerminalConfig->SendCR)
  994.                     {
  995.                         case EOL_LF:
  996.  
  997.                             SerWrite("\n",1);
  998.                             break;
  999.  
  1000.                         case EOL_CR:
  1001.  
  1002.                             SerWrite("\r",1);
  1003.                             break;
  1004.  
  1005.                         case EOL_LFCR:
  1006.  
  1007.                             SerWrite("\n\r",2);
  1008.                             break;
  1009.  
  1010.                         case EOL_CRLF:
  1011.  
  1012.                             SerWrite("\r\n",2);
  1013.                             break;
  1014.                     }
  1015.                 }
  1016.  
  1017.                 break;
  1018.  
  1019.                 /* Restart in/output. */
  1020.  
  1021.             case CHAR_XON:
  1022.  
  1023.                 if(Config->SerialConfig->xONxOFF)
  1024.                     Clear_xOFF();
  1025.  
  1026.                 if(Config->SerialConfig->PassThrough)
  1027.                     SerWrite(&c,1);
  1028.  
  1029.                 break;
  1030.  
  1031.                 /* Stop in/output. */
  1032.  
  1033.             case CHAR_XOFF:
  1034.  
  1035.                 if(Config->SerialConfig->xONxOFF)
  1036.                     Set_xOFF();
  1037.  
  1038.                 if(Config->SerialConfig->PassThrough)
  1039.                     SerWrite(&c,1);
  1040.  
  1041.                 break;
  1042.  
  1043.                 /* Any other character. */
  1044.  
  1045.             case CHAR_VANILLA:
  1046.  
  1047.                 if(Get_xOFF())
  1048.                 {
  1049.                     if(Bell)
  1050.                         BellSignal();
  1051.                 }
  1052.                 else
  1053.                 {
  1054.                     if(Config->TerminalConfig->FontMode == FONT_IBM)
  1055.                     {
  1056.                             /* Convert special
  1057.                              * Amiga characters into
  1058.                              * alien IBM dialect.
  1059.                              */
  1060.  
  1061.                         if(IBMConversion[c])
  1062.                             SerWrite(&IBMConversion[c],1);
  1063.                         else
  1064.                             SerWrite(&c,1);
  1065.                     }
  1066.                     else
  1067.                         SerWrite(&c,1);
  1068.                 }
  1069.  
  1070.                 break;
  1071.         }
  1072.     }
  1073. }
  1074.  
  1075. STATIC VOID
  1076. ClearDialMenu()
  1077. {
  1078.     if(Menu)
  1079.     {
  1080.         struct Menu    *ThisMenu;
  1081.         struct MenuItem    *Item;
  1082.  
  1083.         ClearMenuStrips();
  1084.  
  1085.         for(ThisMenu = Menu ; ThisMenu ; ThisMenu = ThisMenu->NextMenu)
  1086.         {
  1087.             if(Item = ThisMenu->FirstItem)
  1088.             {
  1089.                 do
  1090.                 {
  1091.                     if((ULONG)GTMENUITEM_USERDATA(Item) >= DIAL_MENU_LIMIT)
  1092.                     {
  1093.                         Item->Flags &= ~CHECKED;
  1094.  
  1095.                         if(Item->SubItem)
  1096.                         {
  1097.                             struct MenuItem *SubItem = Item->SubItem;
  1098.  
  1099.                             do
  1100.                                 SubItem->Flags &= ~CHECKED;
  1101.                             while(SubItem = SubItem->NextItem);
  1102.                         }
  1103.                     }
  1104.                 }
  1105.                 while(Item = Item->NextItem);
  1106.             }
  1107.         }
  1108.  
  1109.         ResetMenuStrips(Menu);
  1110.     }
  1111. }
  1112.  
  1113. STATIC BOOL
  1114. DialMenuToDialList()
  1115. {
  1116.     ClearDialMenu();
  1117.  
  1118.     if(QuickDialMax > 0)
  1119.     {
  1120.         BOOL GotAll;
  1121.         LONG i;
  1122.  
  1123.         DeleteDialList(GlobalPhoneHandle);
  1124.  
  1125.         GotAll = TRUE;
  1126.  
  1127.         for(i = 0 ; i < QuickDialMax ; i++)
  1128.         {
  1129.             if(QuickDialTable[i] != -1)
  1130.             {
  1131.                 if(GotAll)
  1132.                     GotAll = AddDialEntry(GlobalPhoneHandle,GlobalPhoneHandle->Phonebook[QuickDialTable[i] - DIAL_MENU_LIMIT],NULL);
  1133.  
  1134.                 QuickDialTable[i] = -1;
  1135.             }
  1136.         }
  1137.  
  1138.         QuickDialMax = 0;
  1139.  
  1140.         if(GotAll)
  1141.             return(TRUE);
  1142.  
  1143.         DeleteDialList(GlobalPhoneHandle);
  1144.     }
  1145.  
  1146.     return(FALSE);
  1147. }
  1148.  
  1149.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  1150.      *
  1151.      *    Skip along the number of selected menu items and
  1152.      *    handle the associated functions.
  1153.      */
  1154.  
  1155. STATIC VOID
  1156. HandleMenu(ULONG Code,ULONG Qualifier)
  1157. {
  1158.     struct MenuItem *MenuItem;
  1159.  
  1160.         /* Check until the last menuitem has been
  1161.          * processed.
  1162.          */
  1163.  
  1164.     while(Code != MENUNULL)
  1165.     {
  1166.             /* Pick up the associated menu item. */
  1167.  
  1168.         if(MenuItem = ItemAddress(Menu,Code))
  1169.         {
  1170.             HandleMenuCode(MenuItem,(ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
  1171.  
  1172.             Code = MenuItem->NextSelect;
  1173.         }
  1174.         else
  1175.             break;
  1176.     }
  1177.  
  1178.         /* Enter the selected entries from the quick dial menu? */
  1179.  
  1180.     if(CheckDialMenu)
  1181.     {
  1182.         CheckDialMenu = FALSE;
  1183.  
  1184.         if(DialMenuToDialList())
  1185.             DoDial = DIAL_LIST;
  1186.     }
  1187. }
  1188.  
  1189.     /* HandleIconify():
  1190.      *
  1191.      *    Handle program iconification.
  1192.      */
  1193.  
  1194. STATIC VOID
  1195. HandleIconify()
  1196. {
  1197.     BOOL Released = FALSE;
  1198.  
  1199.         /* Set the wait mouse pointer... */
  1200.  
  1201.     BlockWindows();
  1202.  
  1203.         /* Open workbench.library. */
  1204.  
  1205.     if(WorkbenchBase)
  1206.     {
  1207.             /* Open icon.library. */
  1208.  
  1209.         if(IconBase)
  1210.         {
  1211.             UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  1212.             struct DiskObject *Icon;
  1213.  
  1214.             strcpy(LocalBuffer,Config->PathConfig->DefaultStorage);
  1215.  
  1216.             if(AddPart(LocalBuffer,"term_SleepIcon",sizeof(LocalBuffer)))
  1217.                 Icon = GetDiskObject(LocalBuffer);
  1218.             else
  1219.                 Icon = NULL;
  1220.  
  1221.             if(!Icon)
  1222.                 Icon = GetDiskObject("PROGDIR:term_SleepIcon");
  1223.  
  1224.             if(!Icon)
  1225.             {
  1226.                 if(!(Icon = GetProgramIcon()))
  1227.                     Icon = GetDefDiskObject(WBTOOL);
  1228.             }
  1229.  
  1230.                 /* Did we get an icon? */
  1231.  
  1232.             if(Icon)
  1233.             {
  1234.                 struct MsgPort *IconPort;
  1235.  
  1236.                     /* Reset the icon type. */
  1237.  
  1238.                 Icon->do_Type = NULL;
  1239.  
  1240.                     /* Default icon position. */
  1241.  
  1242.                 Icon->do_CurrentX = NO_ICON_POSITION;
  1243.                 Icon->do_CurrentY = NO_ICON_POSITION;
  1244.  
  1245.                     /* Create the Workbench reply port. */
  1246.  
  1247.                 if(IconPort = CreateMsgPort())
  1248.                 {
  1249.                     struct AppIcon *AppIcon;
  1250.  
  1251.                         /* Add the application icon. */
  1252.  
  1253.                     if(AppIcon = AddAppIconA(0,0,TermIDString,IconPort,NULL,Icon,NULL))
  1254.                     {
  1255.                         struct AppMessage *AppMessage;
  1256.  
  1257.                             /* Release the window. */
  1258.  
  1259.                         Released = TRUE;
  1260.                         ReleaseWindows();
  1261.  
  1262.                             /* Close the display. full stop. */
  1263.  
  1264.                         if(DeleteDisplay())
  1265.                         {
  1266.                             ULONG Signals;
  1267.  
  1268.                                 /* Reset and release the serial driver. */
  1269.  
  1270.                             if(Config->MiscConfig->ReleaseDevice)
  1271.                             {
  1272.                                 ClearSerial();
  1273.                                 DeleteSerial();
  1274.                             }
  1275.  
  1276.                                 /* Wait for double-click. */
  1277.  
  1278.                             IconTerminated = FALSE;
  1279.  
  1280.                             do
  1281.                             {
  1282.                                 Signals = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
  1283.  
  1284.                                     /* Received a double-click? */
  1285.  
  1286.                                 if(Signals & PORTMASK(IconPort))
  1287.                                 {
  1288.                                         /* Pick up application messages. */
  1289.  
  1290.                                     while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  1291.                                     {
  1292.                                         IconTerminated = TRUE;
  1293.  
  1294.                                         ReplyMsg((struct Message *)AppMessage);
  1295.                                     }
  1296.                                 }
  1297.  
  1298.                                     /* Wake up if ARexx command received. */
  1299.  
  1300.                                 if(Signals & SIG_REXX)
  1301.                                     while(RunJob(RexxJob));
  1302.  
  1303.                                     /* Generic wakeup signal. */
  1304.  
  1305.                                 if(Signals & SIGBREAKF_CTRL_F)
  1306.                                     IconTerminated = TRUE;
  1307.  
  1308.                                     /* Ready to leave? */
  1309.  
  1310.                                 if(IconTerminated)
  1311.                                 {
  1312.                                         /* Open the serial driver. */
  1313.  
  1314.                                     if(Config->MiscConfig->ReleaseDevice)
  1315.                                     {
  1316.                                         if(!CreateSerial(LocalBuffer,sizeof(LocalBuffer)))
  1317.                                         {
  1318.                                             switch(ShowRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),LocalBuffer))
  1319.                                             {
  1320.                                                 case 0:
  1321.  
  1322.                                                     MainTerminated = TRUE;
  1323.                                                     break;
  1324.  
  1325.                                                 case 1:
  1326.  
  1327.                                                     IconTerminated = FALSE;
  1328.                                                     break;
  1329.                                             }
  1330.                                         }
  1331.                                     }
  1332.                                 }
  1333.  
  1334.                                     /* Still ready to leave? */
  1335.  
  1336.                                 if(IconTerminated && !MainTerminated)
  1337.                                 {
  1338.                                     STRPTR String;
  1339.  
  1340.                                         /* Create the display. */
  1341.  
  1342.                                     if(String = CreateDisplay(TRUE,FALSE))
  1343.                                     {
  1344.                                         switch(ShowRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  1345.                                         {
  1346.                                             case 0:
  1347.  
  1348.                                                 MainTerminated = TRUE;
  1349.                                                 break;
  1350.  
  1351.                                             case 1:
  1352.  
  1353.                                                     /* Reset and release the serial driver. */
  1354.  
  1355.                                                 if(Config->MiscConfig->ReleaseDevice)
  1356.                                                 {
  1357.                                                     ClearSerial();
  1358.                                                     DeleteSerial();
  1359.                                                 }
  1360.  
  1361.                                                 IconTerminated = FALSE;
  1362.                                                 break;
  1363.                                         }
  1364.                                     }
  1365.                                     else
  1366.                                     {
  1367.                                         BumpWindow(Window);
  1368.  
  1369.                                         PubScreenStuff();
  1370.                                     }
  1371.                                 }
  1372.                             }
  1373.                             while(!IconTerminated);
  1374.                         }
  1375.                         else
  1376.                         {
  1377.                             BlockWindows();
  1378.  
  1379.                             ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  1380.  
  1381.                             ReleaseWindows();
  1382.                         }
  1383.  
  1384.                             /* Remove the application icon. */
  1385.  
  1386.                         RemoveAppIcon(AppIcon);
  1387.  
  1388.                             /* Reply pending messages. */
  1389.  
  1390.                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  1391.                             ReplyMsg((struct Message *)AppMessage);
  1392.                     }
  1393.                     else
  1394.                         ShowRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1395.  
  1396.                     DeleteMsgPort(IconPort);
  1397.                 }
  1398.                 else
  1399.                     ShowRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1400.  
  1401.                 FreeDiskObject(Icon);
  1402.             }
  1403.             else
  1404.                 ShowRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1405.         }
  1406.         else
  1407.             ShowRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1408.     }
  1409.     else
  1410.         ShowRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1411.  
  1412.     if(!Released)
  1413.         ReleaseWindows();
  1414.  
  1415.         /* Finished! */
  1416.  
  1417.     DoIconify = FALSE;
  1418. }
  1419.  
  1420.     /* HandleOnlineCleanup():
  1421.      *
  1422.      *    Perform offline cleanup tasks.
  1423.      */
  1424.  
  1425. STATIC VOID
  1426. HandleOnlineCleanup(BOOL Hangup)
  1427. {
  1428.     SoundPlay(SOUND_DISCONNECT);
  1429.  
  1430.         /* Execute logoff macro. */
  1431.  
  1432.     if(Config->CommandConfig->LogoffMacro[0] && WasOnline)
  1433.         SerialCommand(Config->CommandConfig->LogoffMacro);
  1434.  
  1435.     StopCall(FALSE);
  1436.  
  1437.         /* Keep the current connection costs */
  1438.  
  1439.     DisplayPay = StopAccountant();
  1440.  
  1441.     SetDialMenu(TRUE);
  1442.  
  1443.     if(!Hangup)
  1444.         Say(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  1445.  
  1446.         /* Clear the password. */
  1447.  
  1448.     Password[0] = 0;
  1449.     UserName[0]    = 0;
  1450.  
  1451.     CurrentBBSName[0]        = 0;
  1452.     CurrentBBSComment[0]    = 0;
  1453.     CurrentBBSNumber[0]        = 0;
  1454.  
  1455.     if(!Config->SerialConfig->CheckCarrier || Config->SerialConfig->DirectConnection)
  1456.     {
  1457.         ObtainSemaphore(&OnlineSemaphore);
  1458.         Online = WasOnline = FALSE;
  1459.         ReleaseSemaphore(&OnlineSemaphore);
  1460.     }
  1461.  
  1462.     SetActivePattern(NULL);
  1463.     SetActiveEntry(GlobalPhoneHandle,NULL);
  1464.  
  1465.     DisarmLimit();
  1466.  
  1467.         /* Previous configuration available? */
  1468.  
  1469.     if(BackupConfig)
  1470.     {
  1471.             /* Remember old configuration. */
  1472.  
  1473.         SaveConfig(Config,PrivateConfig);
  1474.  
  1475.             /* Copy configuration. */
  1476.  
  1477.         SaveConfig(BackupConfig,Config);
  1478.  
  1479.             /* Set up new configuration. */
  1480.  
  1481.         ConfigSetup();
  1482.  
  1483.             /* Free old configuration. */
  1484.  
  1485.         DeleteConfiguration(BackupConfig);
  1486.  
  1487.         BackupConfig = NULL;
  1488.     }
  1489.  
  1490.         /* Display the connection cost next time control */
  1491.         /* passes through the main loop. */
  1492.  
  1493.     ActivateJob(MainJobQueue,DisplayCostJob);
  1494.  
  1495.     DisplayHangup = Hangup;
  1496.  
  1497.     if(Config->ModemConfig->RedialAfterHangup || KeepRedialing)
  1498.     {
  1499.         if(GlobalPhoneHandle->DialList)
  1500.         {
  1501.             if(!IsListEmpty(GlobalPhoneHandle->DialList))
  1502.             {
  1503.                 ObtainSemaphore(&OnlineSemaphore);
  1504.                 Online = WasOnline = FALSE;
  1505.                 ReleaseSemaphore(&OnlineSemaphore);
  1506.  
  1507.                 DoDial = DIAL_LIST;
  1508.             }
  1509.             else
  1510.             {
  1511.                 if(KeepRedialing)
  1512.                 {
  1513.                     KeepRedialing = FALSE;
  1514.  
  1515.                     if(GlobalPhoneHandle->AutoExit)
  1516.                         MainTerminated = TRUE;
  1517.                 }
  1518.             }
  1519.         }
  1520.         else
  1521.             KeepRedialing = FALSE;
  1522.     }
  1523. }
  1524.  
  1525.     /* HandleFlowChange():
  1526.      *
  1527.      *    Handle data flow scanner information.
  1528.      */
  1529.  
  1530. STATIC VOID
  1531. HandleFlowChange()
  1532. {
  1533.     if(Online)
  1534.     {
  1535.         if(FlowInfo.NoCarrier)
  1536.         {
  1537.             if(Config->SerialConfig->CheckCarrier && !Config->SerialConfig->DirectConnection)
  1538.             {
  1539.                     /* Is the carrier still present? */
  1540.  
  1541.                 if(!(GetSerialStatus() & CIAF_COMCD))
  1542.                     FlowInfo.NoCarrier = FALSE;
  1543.             }
  1544.  
  1545.             if(FlowInfo.NoCarrier)
  1546.                 SetOnlineState(FALSE,0);
  1547.         }
  1548.     }
  1549.     else
  1550.     {
  1551.         if(FlowInfo.Voice)
  1552.         {
  1553.             UBYTE DateTimeBuffer[256];
  1554.  
  1555.             FormatStamp(NULL,DateTimeBuffer,sizeof(DateTimeBuffer),FALSE);
  1556.  
  1557.             WakeUp(Window,SOUND_VOICE);
  1558.  
  1559.             ConPrintf(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
  1560.  
  1561.             Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  1562.         }
  1563.  
  1564.         if(FlowInfo.Ring)
  1565.         {
  1566.             UBYTE DateTimeBuffer[256];
  1567.  
  1568.             FormatStamp(NULL,DateTimeBuffer,sizeof(DateTimeBuffer),FALSE);
  1569.  
  1570.             WakeUp(Window,SOUND_RING);
  1571.  
  1572.             ConPrintf(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
  1573.  
  1574.             Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  1575.         }
  1576.  
  1577.         if(FlowInfo.Connect)
  1578.         {
  1579.                 /* Are we to check the carrier signal? */
  1580.  
  1581.             if(Config->SerialConfig->CheckCarrier && !Config->SerialConfig->DirectConnection)
  1582.             {
  1583.                     /* No carrier signal present? */
  1584.  
  1585.                 if(GetSerialStatus() & CIAF_COMCD)
  1586.                     FlowInfo.Connect = FALSE;
  1587.             }
  1588.  
  1589.             if(FlowInfo.Connect)
  1590.             {
  1591.                 WakeUp(Window,SOUND_CONNECT);
  1592.  
  1593.                 SetOnlineState(TRUE,0);
  1594.  
  1595.                 BaudPending = FALSE;
  1596.  
  1597.                 SetDialMenu(FALSE);
  1598.             }
  1599.         }
  1600.     }
  1601.  
  1602.         /* Check if we are to prompt the user for
  1603.          * file transfer.
  1604.          */
  1605.  
  1606.     if(FlowInfo.Signature)
  1607.     {
  1608.         LONG Type = FlowInfo.Signature - SCAN_SIGDEFAULTUPLOAD + TRANSFERSIG_DEFAULTUPLOAD;
  1609.  
  1610.         BlockWindows();
  1611.  
  1612.         switch(Type)
  1613.         {
  1614.             case TRANSFERSIG_DEFAULTUPLOAD:
  1615.  
  1616.                 switch(UploadPanel(TRUE))
  1617.                 {
  1618.                     case UPLOAD_TEXT:
  1619.  
  1620. #ifdef BUILTIN_ZMODEM
  1621.                         if(UseInternalZModem)
  1622.                         {
  1623.                             InternalZModemTextUpload();
  1624.                             break;
  1625.                         }
  1626. #endif    /* BUILTIN_ZMODEM */
  1627.  
  1628.                         StartSendXPR_AskForFile(TRANSFER_TEXT,TRUE);
  1629.                         break;
  1630.  
  1631.                     case UPLOAD_BINARY:
  1632.  
  1633. #ifdef BUILTIN_ZMODEM
  1634.                         if(UseInternalZModem)
  1635.                         {
  1636.                             InternalZModemBinaryUpload();
  1637.                             break;
  1638.                         }
  1639. #endif    /* BUILTIN_ZMODEM */
  1640.  
  1641.                         StartSendXPR_AskForFile(TRANSFER_BINARY,TRUE);
  1642.                         break;
  1643.  
  1644.                     case UPLOAD_ABORT:
  1645.  
  1646.                         CancelZModem();
  1647.                         break;
  1648.  
  1649.                     case UPLOAD_BINARY_FROM_LIST:
  1650.  
  1651.                         HandleUpload(UPLOAD_BINARY);
  1652.                         break;
  1653.  
  1654.                     case UPLOAD_TEXT_FROM_LIST:
  1655.  
  1656.                         HandleUpload(UPLOAD_TEXT);
  1657.                         break;
  1658.                 }
  1659.  
  1660.                 break;
  1661.  
  1662.             case TRANSFERSIG_DEFAULTDOWNLOAD:
  1663.  
  1664. #ifdef BUILTIN_ZMODEM
  1665.                 if(UseInternalZModem)
  1666.                 {
  1667.                     ZReceive();
  1668.                     break;
  1669.                 }
  1670. #endif    /* BUILTIN_ZMODEM */
  1671.  
  1672.                 switch(UploadPanel(FALSE))
  1673.                 {
  1674.                     case UPLOAD_TEXT:
  1675.  
  1676.                         StartReceiveXPR_AskForFile(TRANSFER_TEXT,TRUE);
  1677.                         break;
  1678.  
  1679.                     case UPLOAD_BINARY:
  1680.  
  1681.                         StartReceiveXPR_AskForFile(TRANSFER_BINARY,TRUE);
  1682.                         break;
  1683.                 }
  1684.  
  1685.                 break;
  1686.  
  1687.             case TRANSFERSIG_ASCIIUPLOAD:
  1688.  
  1689.                 if(ChangeProtocol(Config->TransferConfig->ASCIIUploadLibrary,Config->TransferConfig->ASCIIUploadType))
  1690.                     StartSendXPR_AskForFile(TRANSFER_ASCII,TRUE);
  1691.  
  1692.                 ResetProtocol();
  1693.  
  1694.                 break;
  1695.  
  1696.             case TRANSFERSIG_ASCIIDOWNLOAD:
  1697.  
  1698.                 if(ChangeProtocol(Config->TransferConfig->ASCIIDownloadLibrary,Config->TransferConfig->ASCIIDownloadType))
  1699.                     StartReceiveXPR_AskForFile(TRANSFER_ASCII,TRUE);
  1700.  
  1701.                 ResetProtocol();
  1702.  
  1703.                 break;
  1704.  
  1705.             case TRANSFERSIG_TEXTUPLOAD:
  1706.  
  1707. #ifdef BUILTIN_ZMODEM
  1708.                 if(UseInternalZModem)
  1709.                 {
  1710.                     InternalZModemTextUpload();
  1711.                     break;
  1712.                 }
  1713. #endif    /* BUILTIN_ZMODEM */
  1714.  
  1715.                 if(ChangeProtocol(Config->TransferConfig->TextUploadLibrary,Config->TransferConfig->TextUploadType))
  1716.                     StartSendXPR_AskForFile(TRANSFER_TEXT,TRUE);
  1717.  
  1718.                 ResetProtocol();
  1719.  
  1720.                 break;
  1721.  
  1722.             case TRANSFERSIG_TEXTDOWNLOAD:
  1723.  
  1724. #ifdef BUILTIN_ZMODEM
  1725.                 if(UseInternalZModem)
  1726.                 {
  1727.                     ZReceive();
  1728.                     break;
  1729.                 }
  1730. #endif    /* BUILTIN_ZMODEM */
  1731.  
  1732.                 if(ChangeProtocol(Config->TransferConfig->TextDownloadLibrary,Config->TransferConfig->TextDownloadType))
  1733.                     StartReceiveXPR_AskForFile(TRANSFER_TEXT,TRUE);
  1734.  
  1735.                 ResetProtocol();
  1736.  
  1737.                 break;
  1738.  
  1739.             case TRANSFERSIG_BINARYUPLOAD:
  1740.  
  1741. #ifdef BUILTIN_ZMODEM
  1742.                 if(UseInternalZModem)
  1743.                 {
  1744.                     InternalZModemBinaryUpload();
  1745.                     break;
  1746.                 }
  1747. #endif    /* BUILTIN_ZMODEM */
  1748.  
  1749.                 if(ChangeProtocol(Config->TransferConfig->BinaryUploadLibrary,Config->TransferConfig->BinaryUploadType))
  1750.                     StartSendXPR_AskForFile(TRANSFER_BINARY,TRUE);
  1751.  
  1752.                 ResetProtocol();
  1753.  
  1754.                 break;
  1755.  
  1756.             case TRANSFERSIG_BINARYDOWNLOAD:
  1757.  
  1758. #ifdef BUILTIN_ZMODEM
  1759.                 if(UseInternalZModem)
  1760.                 {
  1761.                     ZReceive();
  1762.                     break;
  1763.                 }
  1764. #endif    /* BUILTIN_ZMODEM */
  1765.  
  1766.                 if(ChangeProtocol(Config->TransferConfig->BinaryDownloadLibrary,Config->TransferConfig->BinaryDownloadType))
  1767.                     StartReceiveXPR_AskForFile(TRANSFER_BINARY,TRUE);
  1768.  
  1769.                 ResetProtocol();
  1770.  
  1771.                 break;
  1772.         }
  1773.  
  1774.         ReleaseWindows();
  1775.     }
  1776.  
  1777.     ResetDataFlowFilter();
  1778. }
  1779.  
  1780.     /* FullHangup():
  1781.      *
  1782.      *    In a nutshell, do the full work required to hang up the line.
  1783.      */
  1784.  
  1785. STATIC VOID
  1786. FullHangup(BOOL ForceIt)
  1787. {
  1788.     BlockWindows();
  1789.  
  1790.     DispatchRexxDialMsgList(FALSE);
  1791.  
  1792.     HangUp();
  1793.  
  1794.     ReleaseWindows();
  1795.  
  1796.     if(Config->SerialConfig->CheckCarrier && !ForceIt && !Config->SerialConfig->DirectConnection)
  1797.         HungUp = TRUE;
  1798.     else
  1799.     {
  1800.         SetOnlineState(FALSE,0);
  1801.  
  1802.         HandleOnlineCleanup(TRUE);
  1803.     }
  1804. }
  1805.  
  1806.     /* AskDial(struct Window *Parent):
  1807.      *
  1808.      *    This is called when the user is about to start dialing. If the
  1809.      *    dial button/menu item is available with the protective mode
  1810.      *    enabled, a message will be displayed, asking if the line
  1811.      *    should be hung up before proceeding.
  1812.      */
  1813.  
  1814. STATIC BOOL
  1815. AskDial(struct Window *Parent)
  1816. {
  1817.     if(!DialItemsAvailable)
  1818.     {
  1819.         if(ShowRequest(Parent,LocaleString(MSG_CANNOT_DIAL_BECAUSE_TXT),LocaleString(MSG_DIAL_CANCEL_TXT)))
  1820.             FullHangup(TRUE);
  1821.         else
  1822.             return(FALSE);
  1823.     }
  1824.  
  1825.     return(TRUE);
  1826. }
  1827.  
  1828.     /* GoOnline():
  1829.      *
  1830.      *    Go into online state.
  1831.      */
  1832.  
  1833. STATIC VOID
  1834. GoOnline()
  1835. {
  1836.     SetOnlineState(TRUE,0);
  1837.  
  1838.     BaudCount        = 0;
  1839.     BaudBuffer[0]    = 0;
  1840.     BaudPending        = FALSE;
  1841.  
  1842.     Password[0]        = 0;
  1843.     UserName[0]        = 0;
  1844.  
  1845.     SendStartup        = FALSE;
  1846.  
  1847.     DisarmLimit();
  1848.  
  1849.     CurrentBBSName[0]        = 0;
  1850.     CurrentBBSComment[0]    = 0;
  1851.     CurrentBBSNumber[0]        = 0;
  1852.  
  1853.     SetActivePattern(NULL);
  1854.     SetActiveEntry(GlobalPhoneHandle,NULL);
  1855.  
  1856.     SetDialMenu(FALSE);
  1857. }
  1858.  
  1859. STATIC VOID
  1860. ReadyToDial(struct DataDialMsg *DialMsg)
  1861. {
  1862.     struct GenericDialNode *Node;
  1863.     PhoneEntry **Phonebook;
  1864.     BOOL DidSomething;
  1865.  
  1866.     DidSomething = FALSE;
  1867.  
  1868.     AddTail(&RexxDialMsgList,(struct Node *)DialMsg->DialMsg);
  1869.  
  1870.     Phonebook = GlobalPhoneHandle->Phonebook;
  1871.  
  1872.     while(Node = (struct GenericDialNode *)RemHead(DialMsg->DialList))
  1873.     {
  1874.         if(Node->Index != -1)
  1875.         {
  1876.             if(Node->Index >= 0 && Node->Index < GlobalPhoneHandle->NumPhoneEntries)
  1877.                 DidSomething |= AddDialEntry(GlobalPhoneHandle,Phonebook[Node->Index],NULL);
  1878.         }
  1879.         else
  1880.         {
  1881.             if(Node->Number != NULL)
  1882.                 DidSomething |= AddDialEntry(GlobalPhoneHandle,NULL,Node->Number);
  1883.             else
  1884.             {
  1885.                 LONG i;
  1886.  
  1887.                 for(i = 0 ; i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  1888.                 {
  1889.                     if(!Stricmp(Phonebook[i]->Header->Name,Node->Node.ln_Name))
  1890.                     {
  1891.                         if(Phonebook[i]->Header->Number[0])
  1892.                             DidSomething |= AddDialEntry(GlobalPhoneHandle,Phonebook[i],NULL);
  1893.                     }
  1894.                 }
  1895.             }
  1896.         }
  1897.  
  1898.         FreeVecPooled(Node);
  1899.     }
  1900.  
  1901.     if(DidSomething)
  1902.         DoDial = DIAL_LIST;
  1903. }
  1904.  
  1905. STATIC VOID
  1906. HandleUpload(UBYTE Type)
  1907. {
  1908.     LockGenericList(GenericListTable[GLIST_UPLOAD]);
  1909.  
  1910.     if(GenericListCount(GenericListTable[GLIST_UPLOAD]) > 0)
  1911.     {
  1912.         struct FileTransferInfo *Info;
  1913.  
  1914.         if(!(Info = AllocFileTransferInfo()))
  1915.             UnlockGenericList(GenericListTable[GLIST_UPLOAD]);
  1916.         else
  1917.         {
  1918.             LONG FilesFound;
  1919.             APTR OldPtr;
  1920.             struct Node *Node;
  1921.             BPTR FileLock;
  1922.             D_S(struct FileInfoBlock,FileInfo);
  1923.  
  1924.             FilesFound = 0;
  1925.  
  1926.             DisableDOSRequesters(&OldPtr);
  1927.  
  1928.             for(Node = ((struct List *)GenericListTable[GLIST_UPLOAD])->lh_Head ; Node->ln_Succ ; Node = Node->ln_Succ)
  1929.             {
  1930.                 if(FileLock = Lock(Node->ln_Name,ACCESS_READ))
  1931.                 {
  1932.                     if(Examine(FileLock,FileInfo))
  1933.                     {
  1934.                         if(FileInfo->fib_DirEntryType < 0)
  1935.                         {
  1936.                             if(AddFileTransferNode(Info,Node->ln_Name,FileInfo->fib_Size))
  1937.                                 FilesFound++;
  1938.  
  1939.                             if(Config->TransferConfig->TransferIcons)
  1940.                             {
  1941.                                 UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  1942.                                 BPTR InfoLock;
  1943.  
  1944.                                 LimitedSPrintf(sizeof(LocalBuffer),LocalBuffer,"%s.info",Node->ln_Name);
  1945.  
  1946.                                 if(InfoLock = Lock(LocalBuffer,ACCESS_READ))
  1947.                                 {
  1948.                                     if(Examine(InfoLock,FileInfo))
  1949.                                     {
  1950.                                         if(FileInfo->fib_DirEntryType < 0)
  1951.                                         {
  1952.                                             if(AddFileTransferNode(Info,LocalBuffer,FileInfo->fib_Size))
  1953.                                                 FilesFound++;
  1954.                                         }
  1955.                                     }
  1956.  
  1957.                                     UnLock(InfoLock);
  1958.                                 }
  1959.                             }
  1960.                         }
  1961.                     }
  1962.  
  1963.                     UnLock(FileLock);
  1964.                 }
  1965.             }
  1966.  
  1967.             ClearGenericList(GenericListTable[GLIST_UPLOAD],TRUE);
  1968.  
  1969.             UnlockGenericList(GenericListTable[GLIST_UPLOAD]);
  1970.  
  1971.             EnableDOSRequesters(OldPtr);
  1972.  
  1973.             if(FilesFound)
  1974.             {
  1975.                 BlockWindows();
  1976.  
  1977.                 ReadyFileTransferInfo(Info,FALSE);
  1978.  
  1979.                 FileTransferInfo = Info;
  1980.  
  1981.                 StartSendXPR_FromList(Type == UPLOAD_BINARY ? TRANSFER_BINARY : TRANSFER_TEXT,TRUE);
  1982.  
  1983.                 ReleaseWindows();
  1984.             }
  1985.             else
  1986.                 FreeFileTransferInfo(Info);
  1987.         }
  1988.     }
  1989.     else
  1990.     {
  1991.         UnlockGenericList(GenericListTable[GLIST_UPLOAD]);
  1992.  
  1993.         StartSendXPR_AskForFile(Type == UPLOAD_BINARY ? TRANSFER_BINARY : TRANSFER_TEXT,TRUE);
  1994.     }
  1995. }
  1996.  
  1997.     /* LocalReleaseSerial():
  1998.      *
  1999.      *    Release the serial device driver, then reopen it again.
  2000.      */
  2001.  
  2002. STATIC VOID
  2003. LocalReleaseSerial()
  2004. {
  2005.     BOOL Continue,SerialClosed;
  2006.     APTR OldPtr;
  2007.  
  2008.     DB(kprintf("in: LocalReleaseSerial()\n"));
  2009.  
  2010.     ChangeWindowPtr(&OldPtr,(APTR)Window);
  2011.  
  2012.         /* This might happen if an ARexx user
  2013.          * released the serial device and
  2014.          * failed to reopen it.
  2015.          */
  2016.  
  2017.     if(ReadPort)
  2018.         SerialClosed = FALSE;
  2019.     else
  2020.         SerialClosed = TRUE;
  2021.  
  2022.     DB(kprintf("blockwindows\n"));
  2023.  
  2024.     BlockWindows();
  2025.  
  2026.         /* Prevent catastrophes! */
  2027.  
  2028.     if(!Config->MiscConfig->ProtectiveMode)
  2029.         Continue = TRUE;
  2030.     else
  2031.     {
  2032.         if(Online && !SerialClosed)
  2033.         {
  2034.             if(!ShowRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2035.                 Continue = FALSE;
  2036.             else
  2037.                 Continue = TRUE;
  2038.         }
  2039.         else
  2040.             Continue = TRUE;
  2041.     }
  2042.  
  2043.     DB(kprintf("continue=%ld serialclosed=%ld\n",Continue,SerialClosed));
  2044.  
  2045.     if(Continue)
  2046.     {
  2047.         if(SerialClosed)
  2048.         {
  2049.             DB(kprintf("reopenserial\n"));
  2050.  
  2051.             ReopenSerial();
  2052.         }
  2053.         else
  2054.         {
  2055.             DB(kprintf("clearserial\n"));
  2056.             ClearSerial();
  2057.  
  2058.             DB(kprintf("deleteserial\n"));
  2059.             DeleteSerial();
  2060.  
  2061.             switch(ShowRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber))
  2062.             {
  2063.                 case 0:
  2064.  
  2065.                     MainTerminated = TRUE;
  2066.                     break;
  2067.  
  2068.                 case 1:
  2069.  
  2070.                     ReopenSerial();
  2071.                     break;
  2072.  
  2073.                 case 2:
  2074.  
  2075.                     ActivateJob(MainJobQueue,IconifyJob);
  2076.                     break;
  2077.             }
  2078.         }
  2079.     }
  2080.  
  2081.     RestoreWindowPtr(OldPtr);
  2082.  
  2083.     ReleaseWindows();
  2084.  
  2085.     DB(kprintf("out: LocalReleaseSerial()\n"));
  2086. }
  2087.  
  2088.     /* HandleKeyboardInput():
  2089.      *
  2090.      *    Process the keyboard input.
  2091.      */
  2092.  
  2093. STATIC VOID
  2094. HandleKeyboardInput(UBYTE Char,UWORD Code,ULONG Qualifier,STRPTR InputBuffer,LONG Len)
  2095. {
  2096.         /* Take care of the numeric keypad. */
  2097.  
  2098.     if((Qualifier & IEQUALIFIER_NUMERICPAD) && (Config->EmulationConfig->NumericMode == KEYMODE_APPLICATION))
  2099.     {
  2100.         STATIC STRPTR StringTable[22][2] =
  2101.         {
  2102.             "0",    "\033Op",
  2103.             "1",    "\033Oq",
  2104.             "2",    "\033Or",
  2105.             "3",    "\033Os",
  2106.             "4",    "\033Ot",
  2107.             "5",    "\033Ou",
  2108.             "6",    "\033Ov",
  2109.             "7",    "\033Ow",
  2110.             "8",    "\033Ox",
  2111.             "9",    "\033Oy",
  2112.             "-",    "\033Om",
  2113.             "+",    "\033Ol",    /* This should really be a comma */
  2114.             ".",    "\033On",
  2115.  
  2116.             "(",    "\033OP",
  2117.             "[",    "\033OP",
  2118.             "{",    "\033OP",
  2119.             "]",    "\033OQ",
  2120.             ")",    "\033OQ",
  2121.             "}",    "\033OQ",
  2122.             "/",    "\033OR",
  2123.             "*",    "\033OS",
  2124.  
  2125.             "\r",    "\033OM"
  2126.         };
  2127.  
  2128.         STATIC struct { UBYTE Code; STRPTR String; } CodeTable[18] =
  2129.         {
  2130.             0x0F,    "\033Op",    /* "0" */
  2131.             0x1D,    "\033Oq",    /* "1" */
  2132.             0x1E,    "\033Or",    /* "2" */
  2133.             0x1F,    "\033Os",    /* "3" */
  2134.             0x2D,    "\033Ot",    /* "4" */
  2135.             0x2E,    "\033Ou",    /* "5" */
  2136.             0x2F,    "\033Ov",    /* "6" */
  2137.             0x3D,    "\033Ow",    /* "7" */
  2138.             0x3E,    "\033Ox",    /* "8" */
  2139.             0x3F,    "\033Oy",    /* "9" */
  2140.             0x4A,    "\033Om",    /* "-" */
  2141.             0x5E,    "\033Ol",    /* "+", but this should really be a comma */
  2142.             0x3C,    "\033On",    /* "." */
  2143.  
  2144.             0x5A,    "\033OP",    /* "[" */
  2145.             0x5B,    "\033OQ",    /* "]" */
  2146.             0x5C,    "\033OR",    /* "/" */
  2147.             0x5D,    "\033OS",    /* "*" */
  2148.  
  2149.             0x43,    "\033OM"    /* <cr> */
  2150.         };
  2151.  
  2152.         STRPTR    String = NULL;
  2153.         LONG    i;
  2154.  
  2155.         for(i = 0 ; i < 22 ; i++)
  2156.         {
  2157.             if(Char == StringTable[i][0][0])
  2158.             {
  2159.                 String = StringTable[i][1];
  2160.  
  2161.                 break;
  2162.             }
  2163.         }
  2164.  
  2165.         if(!String)
  2166.         {
  2167.             for(i = 0 ; i < 18 ; i++)
  2168.             {
  2169.                 if(Code == CodeTable[i].Code)
  2170.                 {
  2171.                     String = CodeTable[i].String;
  2172.  
  2173.                     break;
  2174.                 }
  2175.             }
  2176.         }
  2177.  
  2178.         if(String)
  2179.         {
  2180.             if(ClipInput)
  2181.             {
  2182.                 CloseClip();
  2183.  
  2184.                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  2185.             }
  2186.  
  2187.             SerWrite(String,strlen(String));
  2188.  
  2189.             Len = 0;
  2190.         }
  2191.     }
  2192.  
  2193.         /* This looks like a raw, or better, now cooked key. */
  2194.  
  2195.     if(Len)
  2196.     {
  2197.         switch(CharType[Char])
  2198.         {
  2199.             case CHAR_HELP:
  2200.  
  2201.                 GuideDisplay(CONTEXT_MAIN);
  2202.  
  2203.                 Len = 0;
  2204.  
  2205.                 break;
  2206.  
  2207.             case CHAR_CURSOR:
  2208.  
  2209.                 if(ClipInput)
  2210.                 {
  2211.                     CloseClip();
  2212.  
  2213.                     ClipInput = ClipXerox = ClipPrefix = FALSE;
  2214.                 }
  2215.  
  2216.                     /* If in cursor key applications mode,
  2217.                      * send the corresponding string.
  2218.                      */
  2219.  
  2220.                 if(Config->EmulationConfig->CursorMode == KEYMODE_APPLICATION)
  2221.                 {
  2222.                     STATIC STRPTR CursorTable[4] =
  2223.                     {
  2224.                         "\033OA",
  2225.                         "\033OB",
  2226.                         "\033OC",
  2227.                         "\033OD"
  2228.                     };
  2229.  
  2230.                     SerWrite(CursorTable[Char - CUP],3);
  2231.                 }
  2232.                 else
  2233.                 {
  2234.                     LONG QualType;
  2235.  
  2236.                         /* Find the appropriate qualifier. */
  2237.  
  2238.                     if(Qualifier & SHIFT_KEY)
  2239.                         QualType = 1;
  2240.                     else
  2241.                     {
  2242.                         if(Qualifier & ALT_KEY)
  2243.                             QualType = 2;
  2244.                         else
  2245.                         {
  2246.                             if(Qualifier & CONTROL_KEY)
  2247.                                 QualType = 3;
  2248.                             else
  2249.                                 QualType = 0;
  2250.                         }
  2251.                     }
  2252.  
  2253.                         /* Send the corresponding string. */
  2254.  
  2255.                     SerialCommand(CursorKeys->Keys[QualType][Char - CUP]);
  2256.                 }
  2257.  
  2258.                 Len = 0;
  2259.  
  2260.                 break;
  2261.  
  2262.                 /* Any function key pressed? */
  2263.  
  2264.             case CHAR_FUNCTION:
  2265.  
  2266.                 if(ClipInput)
  2267.                 {
  2268.                     CloseClip();
  2269.  
  2270.                     ClipInput = ClipXerox = ClipPrefix = FALSE;
  2271.                 }
  2272.  
  2273.                 if(Qualifier & CONTROL_KEY)
  2274.                     SerialCommand(MacroKeys->Keys[3][Char - FN1]);
  2275.                 else
  2276.                 {
  2277.                     if(Qualifier & ALT_KEY)
  2278.                         SerialCommand(MacroKeys->Keys[2][Char - FN1]);
  2279.                     else
  2280.                     {
  2281.                         if(Qualifier & SHIFT_KEY)
  2282.                             SerialCommand(MacroKeys->Keys[1][Char - FN1]);
  2283.                         else
  2284.                             SerialCommand(MacroKeys->Keys[0][Char - FN1]);
  2285.                     }
  2286.                 }
  2287.  
  2288.                 Len = 0;
  2289.  
  2290.                 break;
  2291.  
  2292.                 /* Anything else? */
  2293.  
  2294.             default:
  2295.  
  2296.                 if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & SHIFT_KEY))
  2297.                 {
  2298.                     RememberInputText("\r",1);
  2299.  
  2300.                     Len = 0;
  2301.  
  2302.                     PopStatus();
  2303.                     PushStatus(STATUS_RECORDING_LINE);
  2304.  
  2305.                     RecordingLine = TRUE;
  2306.  
  2307.                     RememberResetInput();
  2308.  
  2309.                     RememberOutput = FALSE;
  2310.                     RememberInput = TRUE;
  2311.  
  2312.                     CheckItem(MEN_RECORD_LINE,TRUE);
  2313.                 }
  2314.  
  2315.                 break;
  2316.         }
  2317.  
  2318.             /* Any characters to send? */
  2319.  
  2320.         if(Len)
  2321.             SendInputTextBuffer(InputBuffer,Len,TRUE,FALSE);
  2322.     }
  2323. }
  2324.  
  2325.     /* HandleSerialCheckJob():
  2326.      *
  2327.      *    Handle routine checkup actions.
  2328.      */
  2329.  
  2330. BOOL
  2331. HandleSerialCheckJob(JobNode *UnusedJob)
  2332. {
  2333.         /* Attempt to lock the serial device? */
  2334.  
  2335.     if(PollODU)
  2336.     {
  2337.             /* We don't want to poll too often */
  2338.  
  2339.         if(PollODUCount++ >= (5 + ROUTINE_CHECK_INTERVAL - 1) / ROUTINE_CHECK_INTERVAL)
  2340.         {
  2341.             PollODUCount = 0;
  2342.  
  2343.                 /* Still supporting the locking protocol? */
  2344.  
  2345.             if(Config->SerialConfig->UseOwnDevUnit)
  2346.             {
  2347.                 BlockWindows();
  2348.  
  2349.                     /* Give it a try */
  2350.  
  2351.                 if(LockDevice(Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber,NULL,0))
  2352.                 {
  2353.                         /* Check */
  2354.  
  2355.                     ReopenSerial();
  2356.  
  2357.                     PollODU = FALSE;
  2358.                 }
  2359.  
  2360.                 ReleaseWindows();
  2361.             }
  2362.             else
  2363.                 PollODU = FALSE;
  2364.         }
  2365.     }
  2366.  
  2367.         /* Take a look at the carrier signal. */
  2368.  
  2369.     if(Config->SerialConfig->CheckCarrier && WriteRequest && !Config->SerialConfig->DirectConnection)
  2370.     {
  2371.         UWORD Status = GetSerialStatus();
  2372.  
  2373.             /* Still online? */
  2374.  
  2375.         if(Online)
  2376.         {
  2377.                 /* Carrier detect signal lost? */
  2378.  
  2379.             if(Status & CIAF_COMCD)
  2380.                 SetOnlineState(FALSE,0);
  2381.         }
  2382.         else
  2383.         {
  2384.                 /* Is the carrier detect signal
  2385.                  * present?
  2386.                  */
  2387.  
  2388.             if(!(Status & CIAF_COMCD))
  2389.                 GoOnline();
  2390.         }
  2391.     }
  2392.  
  2393.         /* Check online time limit. */
  2394.  
  2395.     if(CheckLimit())
  2396.         LaunchRexxAsync(LimitMacro);
  2397.  
  2398.         /* Flush capture file contents to disk,
  2399.          * this routine is executed each minute
  2400.          * in order to store the captured data.
  2401.          */
  2402.  
  2403.     if(BufferFlushCount++ >= (60 + ROUTINE_CHECK_INTERVAL - 1) / ROUTINE_CHECK_INTERVAL)
  2404.     {
  2405.         BufferFlushCount = 0;
  2406.  
  2407.             /* Flush the capture file. */
  2408.  
  2409.         if(FileCapture)
  2410.             BufferFlush(FileCapture);
  2411.     }
  2412.  
  2413.     return(FALSE);
  2414. }
  2415.  
  2416.     /* HandleQueueJob(JobNode *UnusedJob):
  2417.      *
  2418.      *    Process the special message queue.
  2419.      */
  2420.  
  2421. BOOL
  2422. HandleQueueJob(JobNode *UnusedJob)
  2423. {
  2424.     struct DataMsg *Item;
  2425.  
  2426.     if(Item = GetMsgItem(SpecialQueue))
  2427.     {
  2428.         WORD OldEcho,Type;
  2429.  
  2430.         switch(Item->Type)
  2431.         {
  2432.                 /* Output data. */
  2433.  
  2434.             case DATAMSGTYPE_WRITE:
  2435.  
  2436.                 SerWrite(Item->Data,Item->Size);
  2437.                 break;
  2438.  
  2439.                 /* Execute a command. */
  2440.  
  2441.             case DATAMSGTYPE_SERIALCOMMAND:
  2442.  
  2443.                 SerialCommand(Item->Data);
  2444.                 break;
  2445.  
  2446.                 /* Execute a command, but don't echo it. */
  2447.  
  2448.             case DATAMSGTYPE_SERIALCOMMANDNOECHO:
  2449.  
  2450.                 OldEcho = Config->SerialConfig->Duplex;
  2451.  
  2452.                 Config->SerialConfig->Duplex = DUPLEX_FULL;
  2453.  
  2454.                 SerialCommand(Item->Data);
  2455.  
  2456.                 Config->SerialConfig->Duplex = OldEcho;
  2457.                 break;
  2458.  
  2459.                 /* Output contents of clipboard */
  2460.  
  2461.             case DATAMSGTYPE_WRITECLIP:
  2462.  
  2463.                 if(!ClipInput)
  2464.                 {
  2465.                     if(!OpenClip(Item->Size))
  2466.                         ClipInput = ClipXerox = TRUE;
  2467.                     else
  2468.                         ClipInput = ClipXerox = FALSE;
  2469.                 }
  2470.  
  2471.                     /* Are we reading input from the clipboard? */
  2472.  
  2473.                 if(ClipInput)
  2474.                 {
  2475.                     UBYTE InputBuffer[256];
  2476.                     LONG Len;
  2477.  
  2478.                     if((Len = GetClip(InputBuffer,sizeof(InputBuffer) - 1)) < 0)
  2479.                     {
  2480.                         CloseClip();
  2481.  
  2482.                         ClipInput = FALSE;
  2483.  
  2484.                         if(ClipXerox)
  2485.                         {
  2486.                             if(Config->ClipConfig->InsertSuffix[0])
  2487.                                 SerialCommand(Config->ClipConfig->InsertSuffix);
  2488.  
  2489.                             ClipXerox = FALSE;
  2490.                         }
  2491.  
  2492.                         ClipPrefix = FALSE;
  2493.                     }
  2494.                     else
  2495.                     {
  2496.                         if(!ClipPrefix && ClipXerox)
  2497.                         {
  2498.                             if(Config->ClipConfig->InsertPrefix[0])
  2499.                                 SerialCommand(Config->ClipConfig->InsertPrefix);
  2500.  
  2501.                             ClipPrefix = TRUE;
  2502.                         }
  2503.  
  2504.                         if(Len > 0)
  2505.                             SendInputTextBuffer(InputBuffer,Len,FALSE,Config->ClipConfig->ConvertLF);
  2506.                     }
  2507.                 }
  2508.  
  2509.                 break;
  2510.  
  2511.                 /* Start an upload */
  2512.  
  2513.             case DATAMSGTYPE_UPLOAD:
  2514.  
  2515.                 Type = Item->Size;
  2516.  
  2517.                 DeleteMsgItem((struct MsgItem *)Item);
  2518.                 Item = NULL;
  2519.  
  2520.                 HandleUpload(Type);
  2521.                 break;
  2522.  
  2523.                 /* Call a menu item */
  2524.  
  2525.             case DATAMSGTYPE_MENU:
  2526.  
  2527.                 HandleMenuCode(NULL,(ULONG)Item->Size,(ULONG)Item->Data);
  2528.                 break;
  2529.  
  2530.                 /* Rendezvous with external process */
  2531.  
  2532.             case DATAMSGTYPE_RENDEZVOUS:
  2533.  
  2534.                 if(ReadRequest && WriteRequest)
  2535.                 {
  2536.                         /* Abort serial I/O processing */
  2537.  
  2538.                     ClearSerial();
  2539.  
  2540.                     BlockWindows();
  2541.  
  2542.                         /* Return the message, caution, we're not ready yet */
  2543.  
  2544.                     Forbid();
  2545.  
  2546.                     DeleteMsgItem((struct MsgItem *)Item);
  2547.  
  2548.                     Item = NULL;
  2549.  
  2550.                         /* Prepare to wait... */
  2551.  
  2552.                     WaitForHandshake();
  2553.  
  2554.                         /* Pick up the queue */
  2555.  
  2556.                     RestartSerial();
  2557.  
  2558.                     Permit();
  2559.  
  2560.                     ReleaseWindows();
  2561.                 }
  2562.  
  2563.                 break;
  2564.  
  2565.                 /* Discard current buffer contents */
  2566.  
  2567.             case DATAMSGTYPE_CLEARBUFFER:
  2568.  
  2569.                 FreeBuffer();
  2570.                 break;
  2571.  
  2572.                 /* Redial current dial list */
  2573.  
  2574.             case DATAMSGTYPE_REDIAL:
  2575.  
  2576.                 if(!Online)
  2577.                     DoDial = DIAL_LIST;
  2578.  
  2579.                 break;
  2580.  
  2581.                 /* Hang up the line */
  2582.  
  2583.             case DATAMSGTYPE_HANGUP:
  2584.  
  2585.                 FullHangup(FALSE);
  2586.                 break;
  2587.  
  2588.                 /* Go to online state */
  2589.  
  2590.             case DATAMSGTYPE_GOONLINE:
  2591.  
  2592.                 if(!Online)
  2593.                     GoOnline();
  2594.  
  2595.                 break;
  2596.  
  2597.                 /* Dial a list of numbers */
  2598.  
  2599.             case DATAMSGTYPE_DIAL:
  2600.  
  2601.                 ReadyToDial((struct DataDialMsg *)Item);
  2602.                 break;
  2603.  
  2604.                 /* Output data as if it had come from the main window. */
  2605.  
  2606.             case DATAMSGTYPE_WRITESTRING:
  2607.  
  2608.                 SendInputTextBuffer(Item->Data,Item->Size,TRUE,TRUE);
  2609.                 break;
  2610.  
  2611.                 /* Output data as if it had come from the main window. */
  2612.  
  2613.             case DATAMSGTYPE_WRITESTRING_NOECHO:
  2614.  
  2615.                 OldEcho = Config->SerialConfig->Duplex;
  2616.  
  2617.                 Config->SerialConfig->Duplex = DUPLEX_FULL;
  2618.  
  2619.                 SendInputTextBuffer(Item->Data,Item->Size,TRUE,TRUE);
  2620.  
  2621.                 Config->SerialConfig->Duplex = OldEcho;
  2622.                 break;
  2623.         }
  2624.  
  2625.         if(Item)
  2626.             DeleteMsgItem((struct MsgItem *)Item);
  2627.  
  2628.         return(TRUE);
  2629.     }
  2630.     else
  2631.         return(FALSE);
  2632. }
  2633.  
  2634.     /* HandleOwnDevUnitJob():
  2635.      *
  2636.      *    Deal with the OwnDevUnit signal notification.
  2637.      */
  2638.  
  2639. BOOL
  2640. HandleOwnDevUnitJob(JobNode *UnusedJob)
  2641. {
  2642.     DB(kprintf("handle ODU\n"));
  2643.  
  2644.     if(!Online || !ReadPort || (Online && Config->SerialConfig->ReleaseODUWhenOnline))
  2645.     {
  2646.         if(Config->SerialConfig->SatisfyODURequests == ODU_RELEASE)
  2647.         {
  2648.             DB(kprintf("ODU release\n"));
  2649.             LocalReleaseSerial();
  2650.         }
  2651.  
  2652.         if(Config->SerialConfig->SatisfyODURequests == ODU_WAIT)
  2653.         {
  2654.             BOOL Continue,SerialClosed;
  2655.             APTR OldPtr;
  2656.  
  2657.             DB(kprintf("ODU wait\n"));
  2658.  
  2659.             ChangeWindowPtr(&OldPtr,(APTR)Window);
  2660.  
  2661.                 /* This might happen if an ARexx user
  2662.                  * released the serial device and
  2663.                  * failed to reopen it.
  2664.                  */
  2665.  
  2666.             if(ReadPort)
  2667.                 SerialClosed = FALSE;
  2668.             else
  2669.                 SerialClosed = TRUE;
  2670.  
  2671.             BlockWindows();
  2672.  
  2673.                 /* Prevent catastrophes! */
  2674.  
  2675.             if(Online && !SerialClosed && !Config->SerialConfig->ReleaseODUWhenOnline)
  2676.             {
  2677.                 if(!ShowRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2678.                     Continue = FALSE;
  2679.                 else
  2680.                     Continue = TRUE;
  2681.             }
  2682.             else
  2683.                 Continue = TRUE;
  2684.  
  2685.             if(Continue)
  2686.             {
  2687.                 if(!SerialClosed)
  2688.                 {
  2689.                     ClearSerial();
  2690.  
  2691.                     DeleteSerial();
  2692.                 }
  2693.             }
  2694.  
  2695.             RestoreWindowPtr(OldPtr);
  2696.  
  2697.             ReleaseWindows();
  2698.  
  2699.                 /* Start polling for the device to become */
  2700.                 /* available again */
  2701.  
  2702.             PollODU = TRUE;
  2703.         }
  2704.     }
  2705.  
  2706.     DB(kprintf("ODU done\n"));
  2707.  
  2708.     return(FALSE);
  2709. }
  2710.  
  2711.     /* HandleWindowJob(JobNode *UnusedJob):
  2712.      *
  2713.      *    Just makes a call to HandleWindow().
  2714.      */
  2715.  
  2716. BOOL
  2717. HandleWindowJob(JobNode *UnusedJob)
  2718. {
  2719.     return(HandleWindow());
  2720. }
  2721.  
  2722.     /* HandleWindowAndXEMJob(JobNode *UnusedJob):
  2723.      *
  2724.      *    Calls both HandleXEM() and HandleWindow().
  2725.      */
  2726.  
  2727. BOOL
  2728. HandleWindowAndXEMJob(JobNode *UnusedJob)
  2729. {
  2730.     HandleXEM();
  2731.  
  2732.     return(HandleWindow());
  2733. }
  2734.  
  2735.     /* HandleWindow():
  2736.      *
  2737.      *    This funny part checks the window(s) for incoming
  2738.      *    user input. Menus are handled elsewhere.
  2739.      */
  2740.  
  2741. BOOL
  2742. HandleWindow()
  2743. {
  2744.     STATIC ULONG    ClickSeconds,ClickMicros;
  2745.     STATIC ULONG    LastSeconds,LastMicros;
  2746.     STATIC BOOL        TestingDoubleClick;
  2747.  
  2748.     struct IntuiMessage    *Message;
  2749.     ULONG                 MsgClass,Code,Qualifier,Seconds,Micros;
  2750.     LONG                 MouseX,MouseY,Len,GadgetID;
  2751.     struct Gadget        *Gadget;
  2752.     UBYTE                 Char,InputBuffer[256];
  2753.     struct Window        *IDCMPWindow;
  2754.     BOOL                 Result,WindowJustActivated;
  2755.  
  2756.     Result                = FALSE;
  2757.     WindowJustActivated    = FALSE;
  2758.  
  2759.         /* Are we reading input from the clipboard? */
  2760.  
  2761.     if(ClipInput)
  2762.     {
  2763.         LONG Length = GetClip(InputBuffer,sizeof(InputBuffer) - 1);
  2764.  
  2765.         if(Length < 0)
  2766.         {
  2767.             CloseClip();
  2768.  
  2769.             ClipInput = FALSE;
  2770.  
  2771.             if(ClipXerox)
  2772.             {
  2773.                 if(Config->ClipConfig->InsertSuffix[0])
  2774.                     SerialCommand(Config->ClipConfig->InsertSuffix);
  2775.  
  2776.                 ClipXerox = FALSE;
  2777.             }
  2778.  
  2779.             ClipPrefix = FALSE;
  2780.         }
  2781.         else
  2782.         {
  2783.             if(!ClipPrefix && ClipXerox)
  2784.             {
  2785.                 if(Config->ClipConfig->InsertPrefix[0])
  2786.                     SerialCommand(Config->ClipConfig->InsertPrefix);
  2787.  
  2788.                 ClipPrefix = TRUE;
  2789.             }
  2790.  
  2791.             if(Length > 0)
  2792.                 SendInputTextBuffer(InputBuffer,Length,FALSE,Config->ClipConfig->ConvertLF);
  2793.  
  2794.             Result = TRUE;
  2795.         }
  2796.     }
  2797.  
  2798.         /* Any news in the mail? */
  2799.  
  2800.     if(Message = (struct IntuiMessage *)GetMsg(Window->UserPort))
  2801.     {
  2802.             /* A click into the window should activate it, but
  2803.              * we don't want to have the character snapping activated
  2804.              * under these conditions. In this case we rely upon
  2805.              * Intuition sending the IDCMP_ACTIVEWINDOW and
  2806.              * IDCMP_MOUSEBUTTONS event marked with the same
  2807.              * creation time stamp. Even if the Intuition
  2808.              * implementation should change no harm should
  2809.              * be done.
  2810.              */
  2811.  
  2812.         Seconds    = Message->Seconds;
  2813.         Micros    = Message->Micros;
  2814.  
  2815.         if(Seconds == LastSeconds && Micros == LastMicros && Message->IDCMPWindow == Window)
  2816.         {
  2817.             if(Message->Class == IDCMP_ACTIVEWINDOW || Message->Class == IDCMP_MOUSEBUTTONS)
  2818.                 WindowJustActivated = TRUE;
  2819.         }
  2820.  
  2821.         LastSeconds    = Seconds;
  2822.         LastMicros    = Micros;
  2823.  
  2824.             /* Pick up the pieces. */
  2825.  
  2826.         MsgClass    = Message->Class;
  2827.         Code        = Message->Code;
  2828.         Qualifier    = Message->Qualifier;
  2829.         Gadget        = (struct Gadget *)Message->IAddress;
  2830.  
  2831.         MouseX        = Message->MouseX;
  2832.         MouseY        = Message->MouseY;
  2833.  
  2834.         IDCMPWindow    = Message->IDCMPWindow;
  2835.  
  2836.         Len        = 0;
  2837.         Char    = 0;
  2838.  
  2839.         switch(MsgClass)
  2840.         {
  2841.             case IDCMP_IDCMPUPDATE:
  2842.  
  2843.                 GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
  2844.                 break;
  2845.  
  2846.             case IDCMP_GADGETUP:
  2847.             case IDCMP_GADGETDOWN:
  2848.  
  2849.                 GadgetID = Gadget->GadgetID;
  2850.                 break;
  2851.  
  2852.             case IDCMP_RAWKEY:
  2853.  
  2854.                     /* Perform key conversion. */
  2855.  
  2856.                 if(XEmulatorBase)
  2857.                 {
  2858.                     if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,sizeof(InputBuffer) - 1,Message))
  2859.                         Char = InputBuffer[0];
  2860.                 }
  2861.                 else
  2862.                     Char = KeyConvert(Message,InputBuffer,&Len);
  2863.  
  2864.                 /* Falls through to... */
  2865.  
  2866.             default:
  2867.  
  2868.                 GadgetID = 0;
  2869.                 break;
  2870.         }
  2871.  
  2872.         ReplyMsg((struct Message *)Message);
  2873.  
  2874.             /* The following messages originated from
  2875.              * the fast! macro panel.
  2876.              */
  2877.  
  2878.         if(IDCMPWindow == FastWindow)
  2879.         {
  2880.             switch(MsgClass)
  2881.             {
  2882.                     /* Close the window. */
  2883.  
  2884.                 case IDCMP_CLOSEWINDOW:
  2885.  
  2886.                     CloseFastWindow();
  2887.                     return(TRUE);
  2888.  
  2889.                     /* Gadget or window size change event. */
  2890.  
  2891.                 case IDCMP_GADGETUP:
  2892.                 case IDCMP_NEWSIZE:
  2893.  
  2894.                     HandleFastWindowGadget(MsgClass,Code);
  2895.                     return(TRUE);
  2896.             }
  2897.         }
  2898.  
  2899.             /* Status window activated? */
  2900.  
  2901.         if(IDCMPWindow == StatusWindow)
  2902.         {
  2903.             switch(MsgClass)
  2904.             {
  2905.                 case IDCMP_ACTIVEWINDOW:
  2906.  
  2907.                     if(!Config->ScreenConfig->SplitStatus)
  2908.                         NormalCursor();
  2909.  
  2910.                     break;
  2911.  
  2912.                 case IDCMP_CLOSEWINDOW:
  2913.  
  2914.                     ShakeHands((struct Task *)StatusProcess,SIG_CLOSEWINDOW);
  2915.  
  2916.                     ClearMenuStrip(StatusWindow);
  2917.                     CloseWindowSafely(StatusWindow);
  2918.  
  2919.                     StatusWindow = NULL;
  2920.                     break;
  2921.             }
  2922.         }
  2923.  
  2924.             /* What about the matrix window? */
  2925.  
  2926.         if(IDCMPWindow == MatrixWindow)
  2927.         {
  2928.             if(DispatchMatrixWindow(&MsgClass,Code,Qualifier,Char))
  2929.                 CloseMatrixWindow();
  2930.         }
  2931.  
  2932.             /* Main window message? */
  2933.  
  2934.         if(IDCMPWindow == Window)
  2935.         {
  2936.             switch(MsgClass)
  2937.             {
  2938.                 case IDCMP_GADGETUP:
  2939.  
  2940.                     if(GadgetID == CHAT_GadgetID)
  2941.                         HandleChatGadget(Code);
  2942.  
  2943.                     break;
  2944.  
  2945.                 case IDCMP_GADGETDOWN:
  2946.  
  2947.                     if(GadgetID == CHAT_GadgetID)
  2948.                         MarkChatGadgetAsActive();
  2949.  
  2950.                     break;
  2951.  
  2952.                 case IDCMP_INACTIVEWINDOW:
  2953.  
  2954.                     WindowMarkerInterrupt();
  2955.  
  2956.                     GhostCursor();
  2957.  
  2958.                     break;
  2959.  
  2960.                 case IDCMP_ACTIVEWINDOW:
  2961.  
  2962.                         /* Take care of the chat gadget if necessary */
  2963.  
  2964.                     ActivateChat(TRUE);
  2965.  
  2966.                     NormalCursor();
  2967.  
  2968.                     break;
  2969.  
  2970.                 case IDCMP_NEWSIZE:
  2971.  
  2972.                         /* Is a window clipping region installed? */
  2973.  
  2974.                     if(ClipRegion)
  2975.                     {
  2976.                         struct Rectangle RegionRectangle;
  2977.  
  2978.                             /* Install old region. */
  2979.  
  2980.                         InstallClipRegion(Window->WLayer,OldRegion);
  2981.  
  2982.                             /* Fill in the clipping rectangle. */
  2983.  
  2984.                         RegionRectangle.MinX = Window->BorderLeft;
  2985.                         RegionRectangle.MinY = Window->BorderTop;
  2986.                         RegionRectangle.MaxX = Window->Width - (Window->BorderRight + 1);
  2987.                         RegionRectangle.MaxY = Window->Height - (Window->BorderBottom + 1);
  2988.  
  2989.                             /* Clear previous clipping region. */
  2990.  
  2991.                         ClearRegion(ClipRegion);
  2992.  
  2993.                             /* Set new clipping region. */
  2994.  
  2995.                         OrRectRegion(ClipRegion,&RegionRectangle);
  2996.  
  2997.                             /* Install new clipping region. */
  2998.  
  2999.                         OldRegion = InstallClipRegion(Window->WLayer,ClipRegion);
  3000.                     }
  3001.  
  3002.                     ForceStatusUpdate();
  3003.  
  3004.                     HandleMenuCode(NULL,MEN_RESET_TERMINAL,Qualifier);
  3005.  
  3006.                         /* Take care of the chat gadget if necessary */
  3007.  
  3008.                     ActivateChat(TRUE);
  3009.  
  3010.                     TTYResize();
  3011.  
  3012.                     break;
  3013.  
  3014.                 case IDCMP_CLOSEWINDOW:
  3015.  
  3016.                     HandleMenuCode(NULL,MEN_QUIT,Qualifier);
  3017.                     break;
  3018.  
  3019.                 case IDCMP_MOUSEMOVE:
  3020.  
  3021.                     WindowMarkerMoveMouse();
  3022.                     break;
  3023.  
  3024.                 case IDCMP_MOUSEBUTTONS:
  3025.  
  3026.                     if(Code == SELECTUP)
  3027.                         ActivateChat(TRUE);
  3028.  
  3029.                     if((!WindowJustActivated || Code != SELECTDOWN) && (!XEmulatorBase || Config->TerminalConfig->EmulationMode != EMULATION_EXTERNAL))
  3030.                     {
  3031.                         switch(Code)
  3032.                         {
  3033.                             case SELECTUP:
  3034.  
  3035.                                 WindowMarkerInterrupt();
  3036.                                 break;
  3037.  
  3038.                             case SELECTDOWN:
  3039.  
  3040.                                 MouseX -= WindowLeft;
  3041.  
  3042.                                 if(MouseX < 0)
  3043.                                     MouseX = 0;
  3044.  
  3045.                                 if(MouseX > WindowWidth - 1)
  3046.                                     MouseX = WindowWidth - 1;
  3047.  
  3048.                                 MouseY -= WindowTop;
  3049.  
  3050.                                 if(MouseY < 0)
  3051.                                     MouseY = 0;
  3052.  
  3053.                                 if(MouseY > WindowHeight - 1)
  3054.                                     MouseY = WindowHeight - 1;
  3055.  
  3056.                                 if(Qualifier & CONTROL_KEY)
  3057.                                 {
  3058.                                     LONG FirstX,FirstY;
  3059.  
  3060.                                     FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  3061.                                     FirstY = MouseY / TextFontHeight;
  3062.  
  3063.                                     if(FirstX < RasterWidth && FirstY < RasterHeight)
  3064.                                     {
  3065.                                         UBYTE LocalChar[2];
  3066.  
  3067.                                         SafeObtainSemaphoreShared(&RasterSemaphore);
  3068.  
  3069.                                         LocalChar[0] = Raster[FirstY * RasterWidth + FirstX];
  3070.  
  3071.                                         ReleaseSemaphore(&RasterSemaphore);
  3072.  
  3073.                                         if(LocalChar[0])
  3074.                                         {
  3075.                                             LONG Len;
  3076.  
  3077.                                             if(Qualifier & SHIFT_KEY)
  3078.                                             {
  3079.                                                 LocalChar[1] = '\r';
  3080.                                                 Len = 2;
  3081.                                             }
  3082.                                             else
  3083.                                                 Len = 1;
  3084.  
  3085.                                             SendInputTextBuffer(LocalChar,Len,TRUE,TRUE);
  3086.                                         }
  3087.                                     }
  3088.  
  3089.                                     return(TRUE);
  3090.                                 }
  3091.  
  3092.                                 if((Qualifier & ALT_KEY) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  3093.                                 {
  3094.                                     LONG DeltaX,DeltaY;
  3095.  
  3096.                                     ObtainSemaphore(&TerminalSemaphore);
  3097.  
  3098.                                     DeltaX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator)  - CursorX;
  3099.                                     DeltaY = MouseY / TextFontHeight - CursorY;
  3100.  
  3101.                                     ReleaseSemaphore(&TerminalSemaphore);
  3102.  
  3103.                                     if(DeltaX || DeltaY)
  3104.                                     {
  3105.                                         if(DeltaX > 0)
  3106.                                         {
  3107.                                             DeltaX++;
  3108.  
  3109.                                             while(DeltaX--)
  3110.                                                 SerWrite("\33[C",3);
  3111.                                         }
  3112.  
  3113.                                         if(DeltaX < 0)
  3114.                                         {
  3115.                                             while(DeltaX++)
  3116.                                                 SerWrite("\33[D",3);
  3117.                                         }
  3118.  
  3119.                                         if(DeltaY > 0)
  3120.                                         {
  3121.                                             DeltaY++;
  3122.  
  3123.                                             while(DeltaY--)
  3124.                                                 SerWrite("\33[B",3);
  3125.                                         }
  3126.  
  3127.                                         if(DeltaY < 0)
  3128.                                         {
  3129.                                             while(DeltaY++)
  3130.                                                 SerWrite("\33[A",3);
  3131.                                         }
  3132.                                     }
  3133.  
  3134.                                     return(TRUE);
  3135.                                 }
  3136.  
  3137.                                 if(TestingDoubleClick)
  3138.                                 {
  3139.                                     ULONG CurrentSeconds,CurrentMicros;
  3140.  
  3141.                                     TestingDoubleClick = FALSE;
  3142.  
  3143.                                     CurrentTime(&CurrentSeconds,&CurrentMicros);
  3144.  
  3145.                                     if(DoubleClick(ClickSeconds,ClickMicros,CurrentSeconds,CurrentMicros))
  3146.                                     {
  3147.                                         WindowMarkWord();
  3148.  
  3149.                                         return(TRUE);
  3150.                                     }
  3151.                                 }
  3152.                                 else
  3153.                                 {
  3154.                                     TestingDoubleClick = TRUE;
  3155.  
  3156.                                     CurrentTime(&ClickSeconds,&ClickMicros);
  3157.                                 }
  3158.  
  3159.                                 WindowMarkerStart(Qualifier);
  3160.                                 break;
  3161.                         }
  3162.                     }
  3163.  
  3164.                     break;
  3165.             }
  3166.         }
  3167.  
  3168.             /* Now for general information. */
  3169.  
  3170.         switch(MsgClass)
  3171.         {
  3172.             case IDCMP_REFRESHWINDOW:
  3173.  
  3174.                 BeginRefresh(IDCMPWindow);
  3175.                 EndRefresh(IDCMPWindow,TRUE);
  3176.                 break;
  3177.  
  3178.             case IDCMP_RAWKEY:
  3179.  
  3180.                 HandleKeyboardInput(Char,Code,Qualifier,InputBuffer,Len);
  3181.                 break;
  3182.  
  3183.                 /* A menu item was selected. */
  3184.  
  3185.             case IDCMP_MENUPICK:
  3186.  
  3187.                 HandleMenu(Code,Qualifier);
  3188.  
  3189.                     /* Take care of the chat gadget if necessary */
  3190.  
  3191.                 ActivateChat(TRUE);
  3192.  
  3193.                 break;
  3194.  
  3195.                 /* Menu help is required. */
  3196.  
  3197.             case IDCMP_MENUHELP:
  3198.  
  3199.                 if(MENUNUM(Code) == NOMENU || MENUNUM(Code) > 9 || ITEMNUM(Code) == NOITEM)
  3200.                     GuideDisplay(CONTEXT_MAIN_MENU);
  3201.                 else
  3202.                     GuideDisplay(CONTEXT_PROJECT_MEN + MENUNUM(Code));
  3203.  
  3204.                 break;
  3205.         }
  3206.  
  3207.         return(TRUE);
  3208.     }
  3209.  
  3210.     return(Result);
  3211. }
  3212.  
  3213.     /* HandleMenuCode(ULONG Code,ULONG Qualifier):
  3214.      *
  3215.      *    Handle each function associated with a menu code.
  3216.      */
  3217.  
  3218. VOID
  3219. HandleMenuCode(struct MenuItem *ThisItem,ULONG Code,ULONG Qualifier)
  3220. {
  3221.     struct FileRequester    *FileRequest;
  3222.     UBYTE                     DummyBuffer[MAX_FILENAME_LENGTH];
  3223.  
  3224.     struct Window            *ReqWindow;
  3225.     struct EasyStruct         Easy;
  3226.  
  3227.     BPTR                     SomeFile;
  3228.     APTR                     OldPtr;
  3229.  
  3230.     BOOL                     Checked;
  3231.  
  3232.     switch(Code)
  3233.     {
  3234.             /* Save screen as IFF-ILBM file. */
  3235.  
  3236.         case MEN_SAVE_AS_PICTURE:
  3237.  
  3238.             BlockWindows();
  3239.  
  3240.             DummyBuffer[0] = 0;
  3241.  
  3242.             if(FileRequest = SaveFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),NULL,NULL,DummyBuffer,sizeof(DummyBuffer)))
  3243.             {
  3244.                 FreeAslRequest(FileRequest);
  3245.  
  3246.                 if(!SaveWindow(DummyBuffer,Window))
  3247.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3248.             }
  3249.  
  3250.             ReleaseWindows();
  3251.  
  3252.             break;
  3253.  
  3254.             /* Save screen as ASCII file. */
  3255.  
  3256.         case MEN_SAVE_AS_TEXT:
  3257.  
  3258.             BlockWindows();
  3259.  
  3260.             DummyBuffer[0] = 0;
  3261.  
  3262.             if(FileRequest = SaveFileOverwrite(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),NULL,NULL,DummyBuffer,sizeof(DummyBuffer)))
  3263.             {
  3264.                 LONG Error = 0;
  3265.  
  3266.                 FreeAslRequest(FileRequest);
  3267.  
  3268.                 SomeFile = NULL;
  3269.  
  3270.                 if(GetFileSize(DummyBuffer))
  3271.                 {
  3272.                     switch(ShowRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  3273.                     {
  3274.                         case 0:
  3275.  
  3276.                             SetIoErr(0);
  3277.                             break;
  3278.  
  3279.                         case 1:
  3280.  
  3281.                             SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3282.                             break;
  3283.  
  3284.                         case 2:
  3285.  
  3286.                             SomeFile = OpenToAppend(DummyBuffer,NULL);
  3287.                             break;
  3288.                     }
  3289.                 }
  3290.                 else
  3291.                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3292.  
  3293.                 if(SomeFile)
  3294.                 {
  3295.                     UBYTE *Buffer;
  3296.                     LONG i,j;
  3297.  
  3298.                     for(i = 0 ; i < RasterHeight ; i++)
  3299.                     {
  3300.                         Buffer = &Raster[i * RasterWidth];
  3301.  
  3302.                         j = RasterWidth - 1;
  3303.  
  3304.                         while(j >= 0 && Buffer[j] == ' ')
  3305.                             j--;
  3306.  
  3307.                         if(j >= 0)
  3308.                         {
  3309.                             SetIoErr(0);
  3310.  
  3311.                             if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
  3312.                             {
  3313.                                 Error = IoErr();
  3314.  
  3315.                                 break;
  3316.                             }
  3317.                         }
  3318.  
  3319.                         SetIoErr(0);
  3320.  
  3321.                         if(FWrite(SomeFile,"\n",1,1) < 1)
  3322.                         {
  3323.                             Error = IoErr();
  3324.  
  3325.                             break;
  3326.                         }
  3327.                     }
  3328.  
  3329.                     Close(SomeFile);
  3330.  
  3331.                     AddProtection(DummyBuffer,FIBF_EXECUTE);
  3332.  
  3333.                     if(Config->MiscConfig->CreateIcons)
  3334.                         AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  3335.                 }
  3336.                 else
  3337.                     Error = IoErr();
  3338.  
  3339.                 if(Error)
  3340.                     ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
  3341.             }
  3342.  
  3343.             ReleaseWindows();
  3344.  
  3345.             break;
  3346.  
  3347.             /* Print the screen (pure ASCII). */
  3348.  
  3349.         case MEN_PRINT_SCREEN:
  3350.  
  3351.             BlockWindows();
  3352.  
  3353.             if(RasterEnabled)
  3354.                 PrintSomething(PRINT_SCREEN);
  3355.             else
  3356.                 ShowRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3357.  
  3358.             ReleaseWindows();
  3359.  
  3360.             break;
  3361.  
  3362.             /* Print the screen (graphics). */
  3363.  
  3364.         case MEN_PRINT_SCREEN_AS_GFX:
  3365.  
  3366.             BlockWindows();
  3367.  
  3368.             PrintScreenGfx();
  3369.  
  3370.             ReleaseWindows();
  3371.  
  3372.             break;
  3373.  
  3374.             /* Print the clipboard contents. */
  3375.  
  3376.         case MEN_PRINT_CLIP:
  3377.  
  3378.             BlockWindows();
  3379.  
  3380.             PrintSomething(PRINT_CLIP);
  3381.  
  3382.             ReleaseWindows();
  3383.  
  3384.             break;
  3385.  
  3386.             /* Open/close the terminal capture file. */
  3387.  
  3388.         case MEN_CAPTURE_TO_FILE:
  3389.  
  3390.             if(FileCapture)
  3391.                 CloseFileCapture();
  3392.             else
  3393.                 OpenFileCapture(FALSE);
  3394.  
  3395.             break;
  3396.  
  3397.             /* Open/close the terminal capture file. */
  3398.  
  3399.         case MEN_CAPTURE_TO_RAW_FILE:
  3400.  
  3401.             if(FileCapture)
  3402.                 CloseFileCapture();
  3403.             else
  3404.                 OpenFileCapture(TRUE);
  3405.  
  3406.             break;
  3407.  
  3408.             /* Start/terminate the printer
  3409.              * capture.
  3410.              */
  3411.  
  3412.         case MEN_CAPTURE_TO_PRINTER:
  3413.  
  3414.             if(PrinterCapture)
  3415.                 ClosePrinterCapture(TRUE);
  3416.             else
  3417.                 OpenPrinterCapture(FALSE);
  3418.  
  3419.             break;
  3420.  
  3421.             /* Iconify the program. */
  3422.  
  3423.         case MEN_ICONIFY:
  3424.  
  3425.             if(Config->MiscConfig->ProtectiveMode)
  3426.             {
  3427.                 if(Online && Config->MiscConfig->ReleaseDevice && !(Qualifier & SHIFT_KEY))
  3428.                 {
  3429.                     BlockWindows();
  3430.  
  3431.                     if(!ShowRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  3432.                     {
  3433.                         ReleaseWindows();
  3434.  
  3435.                         break;
  3436.                     }
  3437.  
  3438.                     ReleaseWindows();
  3439.                 }
  3440.             }
  3441.  
  3442.             ActivateJob(MainJobQueue,IconifyJob);
  3443.  
  3444.             break;
  3445.  
  3446.             /* Say who we are. */
  3447.  
  3448.         case MEN_ABOUT:
  3449.  
  3450.             if(Qualifier & IEQUALIFIER_LSHIFT)
  3451.                 StartTerminalTest(Qualifier);
  3452.             else
  3453.             {
  3454.                 BlockWindows();
  3455.                 ShowAbout(FALSE);
  3456.                 ReleaseWindows();
  3457.             }
  3458.  
  3459.             break;
  3460.  
  3461.             /* Terminate the program. */
  3462.  
  3463.         case MEN_QUIT:
  3464.  
  3465.             if((Qualifier & SHIFT_KEY) || !Config->MiscConfig->ProtectiveMode)
  3466.                 MainTerminated = TRUE;
  3467.             else
  3468.             {
  3469.                 LONG OldLen,Len;
  3470.                 STRPTR Buffer;
  3471.  
  3472.                 OldLen = Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
  3473.  
  3474.                 if(Online)
  3475.                     Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
  3476.  
  3477.                 if(BufferChanged)
  3478.                     Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
  3479.  
  3480.                 if(ConfigChanged)
  3481.                     Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
  3482.  
  3483.                 if(PhonebookChanged)
  3484.                     Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
  3485.  
  3486.                 if(TranslationChanged)
  3487.                     Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
  3488.  
  3489.                 if(MacroChanged)
  3490.                     Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
  3491.  
  3492.                 if(CursorKeysChanged)
  3493.                     Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
  3494.  
  3495.                 if(FastMacrosChanged)
  3496.                     Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
  3497.  
  3498.                 if(HotkeysChanged)
  3499.                     Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
  3500.  
  3501.                 if(SpeechChanged)
  3502.                     Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
  3503.  
  3504.                 if(SoundChanged)
  3505.                     Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
  3506.  
  3507.                 BlockWindows();
  3508.  
  3509.                 ChangeWindowPtr(&OldPtr,(APTR)Window);
  3510.  
  3511.                 if(OldLen != Len)
  3512.                 {
  3513.                     if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
  3514.                     {
  3515.                         LimitedSPrintf(Len,Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
  3516.  
  3517.                         if(Online)
  3518.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
  3519.  
  3520.                         if(BufferChanged)
  3521.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
  3522.  
  3523.                         if(ConfigChanged)
  3524.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
  3525.  
  3526.                         if(PhonebookChanged)
  3527.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
  3528.  
  3529.                         if(TranslationChanged)
  3530.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
  3531.  
  3532.                         if(MacroChanged)
  3533.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
  3534.  
  3535.                         if(CursorKeysChanged)
  3536.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
  3537.  
  3538.                         if(FastMacrosChanged)
  3539.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
  3540.  
  3541.                         if(HotkeysChanged)
  3542.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
  3543.  
  3544.                         if(SpeechChanged)
  3545.                             FormatAppend(Buffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
  3546.  
  3547.                         if(ShowRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  3548.                             MainTerminated = TRUE;
  3549.  
  3550.                         FreeVecPooled(Buffer);
  3551.                     }
  3552.                     else
  3553.                         MainTerminated = TRUE;
  3554.                 }
  3555.                 else
  3556.                     MainTerminated = TRUE;
  3557.  
  3558.                 RestoreWindowPtr(OldPtr);
  3559.  
  3560.                 ReleaseWindows();
  3561.             }
  3562.  
  3563.             break;
  3564.  
  3565.             /* Feed the contents of the clipboard
  3566.              * into the input stream.
  3567.              */
  3568.  
  3569.         case MEN_PASTE:
  3570.  
  3571.             if(!OpenClip(Config->ClipConfig->ClipboardUnit))
  3572.             {
  3573.                 ClipInput = TRUE;
  3574.  
  3575.                 if(Qualifier & SHIFT_KEY)
  3576.                     ClipXerox = TRUE;
  3577.             }
  3578.             else
  3579.                 ClipInput = FALSE;
  3580.  
  3581.             break;
  3582.  
  3583.         case MEN_COPY:
  3584.  
  3585.             WindowMarkerTransfer(Qualifier);
  3586.             break;
  3587.  
  3588.         case MEN_CLEAR:
  3589.  
  3590.             WindowMarkerStop();
  3591.             break;
  3592.  
  3593.         case MEN_SELECT_ALL:
  3594.  
  3595.             WindowMarkerSelectAll();
  3596.             break;
  3597.  
  3598.             /* Execute an AmigaDOS command. */
  3599.  
  3600.         case MEN_EXECUTE_DOS_COMMAND:
  3601.  
  3602.             BlockWindows();
  3603.  
  3604.                 /* Enter the name of the command. */
  3605.  
  3606.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
  3607.             {
  3608.                 if(AmigaDOSCommandBuffer[0])
  3609.                     LaunchCommandAsync(AmigaDOSCommandBuffer);
  3610.             }
  3611.  
  3612.             ReleaseWindows();
  3613.  
  3614.             break;
  3615.  
  3616.             /* Execute an ARexx script command. */
  3617.  
  3618.         case MEN_EXECUTE_REXX_COMMAND:
  3619.  
  3620.             BlockWindows();
  3621.  
  3622.                 /* Get the rexx file name/program. */
  3623.  
  3624.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
  3625.             {
  3626.                 if(ARexxCommandBuffer[0])
  3627.                     LaunchRexxAsync(ARexxCommandBuffer);
  3628.             }
  3629.  
  3630.             ReleaseWindows();
  3631.  
  3632.             break;
  3633.  
  3634.             /* Turn recording on/off. */
  3635.  
  3636.         case MEN_RECORD:
  3637.  
  3638.             if(GetItem(MEN_RECORD))
  3639.             {
  3640.                 if(!Recording)
  3641.                 {
  3642.                     if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
  3643.                     {
  3644.                         RememberResetOutput();
  3645.                         RememberResetInput();
  3646.  
  3647.                         RememberOutput = TRUE;
  3648.  
  3649.                         Recording = TRUE;
  3650.                         RecordingLine = FALSE;
  3651.  
  3652.                         PushStatus(STATUS_RECORDING);
  3653.  
  3654.                         OnItem(MEN_RECORD_LINE);
  3655.                     }
  3656.                 }
  3657.             }
  3658.             else
  3659.             {
  3660.                 if(Recording)
  3661.                 {
  3662.                     FinishRecord();
  3663.  
  3664.                     RememberOutput = FALSE;
  3665.                     RememberInput = FALSE;
  3666.  
  3667.                     Recording = FALSE;
  3668.                     RecordingLine = FALSE;
  3669.  
  3670.                     PopStatus();
  3671.  
  3672.                     OffItem(MEN_RECORD_LINE);
  3673.                 }
  3674.             }
  3675.  
  3676.             break;
  3677.  
  3678.         case MEN_RECORD_LINE:
  3679.  
  3680.             if(Recording)
  3681.             {
  3682.                 if(GetItem(MEN_RECORD))
  3683.                 {
  3684.                     if(!RecordingLine)
  3685.                     {
  3686.                         PopStatus();
  3687.                         PushStatus(STATUS_RECORDING_LINE);
  3688.  
  3689.                         RecordingLine = TRUE;
  3690.  
  3691.                         RememberResetInput();
  3692.  
  3693.                         RememberOutput = FALSE;
  3694.                         RememberInput = TRUE;
  3695.                     }
  3696.                 }
  3697.                 else
  3698.                 {
  3699.                     if(RecordingLine)
  3700.                     {
  3701.                         PopStatus();
  3702.                         PushStatus(STATUS_RECORDING);
  3703.  
  3704.                         RememberSpill();
  3705.  
  3706.                         RecordingLine = FALSE;
  3707.  
  3708.                         RememberOutput = TRUE;
  3709.                         RememberInput = FALSE;
  3710.                     }
  3711.                 }
  3712.             }
  3713.  
  3714.             break;
  3715.  
  3716.         case MEN_DISABLE_TRAPS:
  3717.  
  3718.             Checked = GetItem(MEN_DISABLE_TRAPS);
  3719.  
  3720.             if(Checked || GenericListCount(GenericListTable[GLIST_TRAP]) == 0)
  3721.                 WatchTraps = FALSE;
  3722.             else
  3723.                 WatchTraps = TRUE;
  3724.  
  3725.             break;
  3726.  
  3727.             /* Edit the trap settings? */
  3728.  
  3729.         case MEN_EDIT_TRAPS:
  3730.  
  3731.             BlockWindows();
  3732.  
  3733.             TrapPanelConfig(Config,&TrapsChanged);
  3734.  
  3735.             CheckItem(MEN_DISABLE_TRAPS,!WatchTraps);
  3736.  
  3737.             ReleaseWindows();
  3738.  
  3739.             break;
  3740.  
  3741.             /* Open the phonebook and dial the
  3742.              * list of entries the user will select.
  3743.              */
  3744.  
  3745.         case MEN_PHONEBOOK:
  3746.  
  3747.             BlockWindows();
  3748.  
  3749.             if(PhonePanel(Qualifier))
  3750.             {
  3751.                 if(AskDial(Window))
  3752.                     DoDial = DIAL_LIST;
  3753.             }
  3754.  
  3755.             ReleaseWindows();
  3756.  
  3757.             break;
  3758.  
  3759.             /* Redial those dial list entries which
  3760.              * we were unable to connect.
  3761.              */
  3762.  
  3763.         case MEN_REDIAL:
  3764.  
  3765.             BlockWindows();
  3766.  
  3767.                 /* If the modem is still online, provide help. */
  3768.  
  3769.             if(AskDial(Window))
  3770.                 DoDial = DIAL_LIST;
  3771.  
  3772.             ReleaseWindows();
  3773.  
  3774.             break;
  3775.  
  3776.             /* Dial a single number. */
  3777.  
  3778.         case MEN_DIAL_NUMBER:
  3779.  
  3780.             BlockWindows();
  3781.  
  3782.                 /* If the modem is still online, provide help. */
  3783.  
  3784.             if(AskDial(Window))
  3785.             {
  3786.                 if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DialNumberBuffer))
  3787.                 {
  3788.                     if(DialNumberBuffer[0])
  3789.                     {
  3790.                             /* Remove all entries from the list. */
  3791.  
  3792.                         DeleteDialList(GlobalPhoneHandle);
  3793.  
  3794.                         if(AddDialEntry(GlobalPhoneHandle,NULL,DialNumberBuffer))
  3795.                             DoDial = DIAL_LIST;
  3796.                     }
  3797.                 }
  3798.             }
  3799.  
  3800.             ReleaseWindows();
  3801.  
  3802.             break;
  3803.  
  3804.             /* Send a break across the serial line. */
  3805.  
  3806.         case MEN_SEND_BREAK:
  3807.  
  3808.             SendBreak();
  3809.             break;
  3810.  
  3811.             /* Hang up the phone line. */
  3812.  
  3813.         case MEN_HANG_UP:
  3814.  
  3815.             FullHangup(FALSE);
  3816.  
  3817.             break;
  3818.  
  3819.             /* Wait a bit... */
  3820.  
  3821.         case MEN_WAIT:
  3822.  
  3823.             Easy.es_StructSize        = sizeof(struct EasyStruct);
  3824.             Easy.es_Flags            = NULL;
  3825.             Easy.es_Title            = LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  3826.             Easy.es_GadgetFormat    = LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  3827.             Easy.es_TextFormat        = LocaleString(MSG_TERMMAIN_WAITING_TXT);
  3828.  
  3829.             BlockWindows();
  3830.  
  3831.             if(ReqWindow = BuildEasyRequest(Window,&Easy,IDCMP_RAWKEY,NULL))
  3832.             {
  3833.                 ULONG Signals,Mask,Which;
  3834.                 LONG Seconds;
  3835.                 BOOL More;
  3836.  
  3837.                     /* Don't echo serial output. */
  3838.  
  3839.             /*    Quiet = TRUE; */
  3840.  
  3841.                 if(!(Seconds = Config->MiscConfig->WaitDelay))
  3842.                     Seconds = 1;
  3843.  
  3844.                 SerialCommand(Config->MiscConfig->WaitString);
  3845.                 RunJob(SerialJob);
  3846.  
  3847.                 StartTime(Seconds,0);
  3848.  
  3849.                 if(ReadPort && !Get_xOFF() && ProcessIO)
  3850.                     Mask = SIG_SERIAL;
  3851.                 else
  3852.                     Mask = NULL;
  3853.  
  3854.                 More = FALSE;
  3855.  
  3856.                 FOREVER
  3857.                 {
  3858.                     Which = Mask | SIG_REXX | SIG_TIMER | PORTMASK(ReqWindow->UserPort);
  3859.  
  3860.                     if(More)
  3861.                     {
  3862.                         Signals = SetSignal(0,Which) & Which;
  3863.                         More = FALSE;
  3864.                     }
  3865.                     else
  3866.                         Signals = Wait(Which);
  3867.  
  3868.                     if(Signals & PORTMASK(ReqWindow->UserPort))
  3869.                     {
  3870.                         ULONG IDCMP = NULL;
  3871.                         LONG Result;
  3872.  
  3873.                         Result = SysReqHandler(ReqWindow,&IDCMP,FALSE);
  3874.  
  3875.                         if(Result == 0 || (Result == -2 && !(IDCMP & IDCMP_RAWKEY)))
  3876.                         {
  3877.                             StopTime();
  3878.  
  3879.                             SerialCommand(Config->MiscConfig->WaitString);
  3880.  
  3881.                             break;
  3882.                         }
  3883.                     }
  3884.  
  3885.                     if(Signals & SIG_TIMER)
  3886.                     {
  3887.                         WaitTime();
  3888.  
  3889.                         SerialCommand(Config->MiscConfig->WaitString);
  3890.  
  3891.                         StartTime(Seconds,0);
  3892.                     }
  3893.  
  3894.                     if(Signals & Mask)
  3895.                     {
  3896.                         More = RunJob(SerialJob);
  3897.  
  3898.                         if(Get_xOFF())
  3899.                         {
  3900.                             Mask = NULL;
  3901.                             More = FALSE;
  3902.                         }
  3903.                     }
  3904.  
  3905.                     if(Signals & SIG_REXX)
  3906.                     {
  3907.                         struct RexxMsg *Msg;
  3908.  
  3909.                         if(Msg = (struct RexxMsg *)GetMsg(TermRexxPort))
  3910.                         {
  3911.                             Msg->rm_Result1 = RC_ERROR;
  3912.                             Msg->rm_Result2 = ERR10_001;
  3913.  
  3914.                             ReplyMsg((struct Message *)Msg);
  3915.  
  3916.                             More = TRUE;
  3917.                         }
  3918.                     }
  3919.                 }
  3920.  
  3921.                 RunJob(SerialJob);
  3922.  
  3923.             /*    Quiet = FALSE; */
  3924.  
  3925.                 FreeSysRequest(ReqWindow);
  3926.             }
  3927.  
  3928.             ReleaseWindows();
  3929.  
  3930.             break;
  3931.  
  3932.             /* Flush the serial buffers. */
  3933.  
  3934.         case MEN_FLUSH_BUFFER:
  3935.  
  3936.             ClearSerial();
  3937.  
  3938.             RestartSerial();
  3939.  
  3940.             break;
  3941.  
  3942.             /* Release the serial device for other
  3943.              * applications.
  3944.              */
  3945.  
  3946.         case MEN_RELEASE_DEVICE:
  3947.  
  3948.             ActivateJob(MainJobQueue,ReleaseSerialJob);
  3949.             break;
  3950.  
  3951.         case MEN_UPLOAD_ASCII:
  3952.  
  3953.             BlockWindows();
  3954.  
  3955.             if(ChangeProtocol(Config->TransferConfig->ASCIIUploadLibrary,Config->TransferConfig->ASCIIUploadType))
  3956.                 StartSendXPR_AskForFile(TRANSFER_ASCII,TRUE);
  3957.  
  3958.             ResetProtocol();
  3959.  
  3960.             ReleaseWindows();
  3961.  
  3962.             break;
  3963.  
  3964.         case MEN_DOWNLOAD_ASCII:
  3965.  
  3966.             BlockWindows();
  3967.  
  3968.             if(ChangeProtocol(Config->TransferConfig->ASCIIDownloadLibrary,Config->TransferConfig->ASCIIDownloadType))
  3969.                 StartReceiveXPR_AskForFile(TRANSFER_ASCII,TRUE);
  3970.  
  3971.             ResetProtocol();
  3972.  
  3973.             ReleaseWindows();
  3974.  
  3975.             break;
  3976.  
  3977.         case MEN_UPLOAD_TEXT:
  3978.  
  3979.             BlockWindows();
  3980.  
  3981. #ifdef BUILTIN_ZMODEM
  3982.             if(UseInternalZModem)
  3983.             {
  3984.                 InternalZModemTextUpload();
  3985.  
  3986.                 ReleaseWindows();
  3987.                 break;
  3988.             }
  3989. #endif    /* BUILTIN_ZMODEM */
  3990.  
  3991.             if(ChangeProtocol(Config->TransferConfig->TextUploadLibrary,Config->TransferConfig->TextUploadType))
  3992.                 StartSendXPR_AskForFile(TRANSFER_TEXT,TRUE);
  3993.  
  3994.             ResetProtocol();
  3995.  
  3996.             ReleaseWindows();
  3997.  
  3998.             break;
  3999.  
  4000.         case MEN_DOWNLOAD_TEXT:
  4001.  
  4002.             BlockWindows();
  4003.  
  4004. #ifdef BUILTIN_ZMODEM
  4005.             if(UseInternalZModem)
  4006.             {
  4007.                 ZReceive();
  4008.  
  4009.                 ReleaseWindows();
  4010.                 break;
  4011.             }
  4012. #endif    /* BUILTIN_ZMODEM */
  4013.  
  4014.             if(ChangeProtocol(Config->TransferConfig->TextDownloadLibrary,Config->TransferConfig->TextDownloadType))
  4015.                 StartReceiveXPR_AskForFile(TRANSFER_TEXT,TRUE);
  4016.  
  4017.             ResetProtocol();
  4018.  
  4019.             ReleaseWindows();
  4020.  
  4021.             break;
  4022.  
  4023.             /* Edit and transfer a file. */
  4024.  
  4025.         case MEN_EDIT_AND_UPLOAD_TEXT:
  4026.  
  4027.             BlockWindows();
  4028.  
  4029.             if(!Config->PathConfig->Editor[0])
  4030.                 GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config->PathConfig->Editor);
  4031.  
  4032.             if(Config->PathConfig->Editor[0])
  4033.             {
  4034.                 DummyBuffer[0] = 0;
  4035.  
  4036.                 if(FileRequest = OpenSingleFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),LocaleString(MSG_TERMMAIN_EDIT_TXT),NULL,DummyBuffer,sizeof(DummyBuffer)))
  4037.                 {
  4038.                     UBYTE CompoundName[2 * MAX_FILENAME_LENGTH];
  4039.  
  4040.                     FreeAslRequest(FileRequest);
  4041.  
  4042.                     LimitedStrcpy(sizeof(CompoundName),CompoundName,Config->PathConfig->Editor);
  4043.                     LimitedStrcat(sizeof(CompoundName),CompoundName," \"");
  4044.                     LimitedStrcat(sizeof(CompoundName),CompoundName,DummyBuffer);
  4045.                     LimitedStrcat(sizeof(CompoundName),CompoundName,"\"");
  4046.  
  4047.                     LaunchCommand(CompoundName);
  4048.  
  4049.                     BumpWindow(Window);
  4050.  
  4051.                     if(GetFileSize(DummyBuffer))
  4052.                     {
  4053.                         switch(ShowRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  4054.                         {
  4055.                             case 1:
  4056.  
  4057.                                 if(ChangeProtocol(Config->TransferConfig->ASCIIUploadLibrary,Config->TransferConfig->ASCIIUploadType))
  4058.                                     StartSendXPR_File(TRANSFER_ASCII,DummyBuffer,TRUE);
  4059.  
  4060.                                 ResetProtocol();
  4061.  
  4062.                                 break;
  4063.  
  4064.                             case 2:
  4065.  
  4066.                                 if(ChangeProtocol(Config->TransferConfig->TextUploadLibrary,Config->TransferConfig->TextUploadType))
  4067.                                     StartSendXPR_File(TRANSFER_TEXT,DummyBuffer,TRUE);
  4068.  
  4069.                                 ResetProtocol();
  4070.  
  4071.                                 break;
  4072.                         }
  4073.                     }
  4074.                 }
  4075.             }
  4076.  
  4077.             ReleaseWindows();
  4078.             break;
  4079.  
  4080.         case MEN_UPLOAD_BINARY:
  4081.  
  4082.             BlockWindows();
  4083.  
  4084. #ifdef BUILTIN_ZMODEM
  4085.             if(UseInternalZModem)
  4086.             {
  4087.                 InternalZModemBinaryUpload();
  4088.  
  4089.                 ReleaseWindows();
  4090.                 break;
  4091.             }
  4092. #endif    /* BUILTIN_ZMODEM */
  4093.  
  4094.             if(ChangeProtocol(Config->TransferConfig->BinaryUploadLibrary,Config->TransferConfig->BinaryUploadType))
  4095.                 StartSendXPR_AskForFile(TRANSFER_BINARY,TRUE);
  4096.  
  4097.             ResetProtocol();
  4098.  
  4099.             ReleaseWindows();
  4100.  
  4101.             break;
  4102.  
  4103.             /* Download some files. */
  4104.  
  4105.         case MEN_DOWNLOAD_BINARY:
  4106.  
  4107.             BlockWindows();
  4108.  
  4109. #ifdef BUILTIN_ZMODEM
  4110.             if(UseInternalZModem)
  4111.             {
  4112.                 ZReceive();
  4113.  
  4114.                 ReleaseWindows();
  4115.                 break;
  4116.             }
  4117. #endif    /* BUILTIN_ZMODEM */
  4118.  
  4119.             if(ChangeProtocol(Config->TransferConfig->BinaryDownloadLibrary,Config->TransferConfig->BinaryDownloadType))
  4120.                 StartReceiveXPR_AskForFile(TRANSFER_BINARY,TRUE);
  4121.  
  4122.             ResetProtocol();
  4123.  
  4124.             ReleaseWindows();
  4125.  
  4126.             break;
  4127.  
  4128.             /* Clear the contents of the scrollback
  4129.              * buffer.
  4130.              */
  4131.  
  4132.         case MEN_CLEAR_BUFFER:
  4133.  
  4134.             if(Lines)
  4135.             {
  4136.                 BlockWindows();
  4137.  
  4138.                 if((Qualifier & SHIFT_KEY) || !Config->MiscConfig->ProtectiveMode)
  4139.                 {
  4140.                     FreeBuffer();
  4141.  
  4142.                     TerminateBuffer();
  4143.                 }
  4144.                 else
  4145.                 {
  4146.                     if(ShowRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  4147.                     {
  4148.                         FreeBuffer();
  4149.  
  4150.                         TerminateBuffer();
  4151.                     }
  4152.                 }
  4153.  
  4154.                 ReleaseWindows();
  4155.             }
  4156.  
  4157.             break;
  4158.  
  4159.             /* Display the scrollback buffer.
  4160.              * Notify the scrollback task or
  4161.              * fire it off if appropriate.
  4162.              */
  4163.  
  4164.         case MEN_DISPLAY_BUFFER:
  4165.  
  4166.             if(!LaunchBuffer())
  4167.             {
  4168.                 BlockWindows();
  4169.  
  4170.                 ShowRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4171.  
  4172.                 ReleaseWindows();
  4173.             }
  4174.  
  4175.             break;
  4176.  
  4177.             /* Close the buffer display. */
  4178.  
  4179.         case MEN_CLOSE_BUFFER:
  4180.  
  4181.             TerminateBuffer();
  4182.             break;
  4183.  
  4184.             /* Is the buffer to be frozen? */
  4185.  
  4186.         case MEN_FREEZE_BUFFER:
  4187.  
  4188.             BufferFrozen = GetItem(MEN_FREEZE_BUFFER);
  4189.             ConOutputUpdate();
  4190.  
  4191.             break;
  4192.  
  4193.             /* Load the buffer contents from a file. */
  4194.  
  4195.         case MEN_OPEN_BUFFER:
  4196.  
  4197.             BlockWindows();
  4198.  
  4199.             DummyBuffer[0] = 0;
  4200.  
  4201.             if(FileRequest = OpenSingleFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),LocaleString(MSG_GLOBAL_LOAD_TXT),NULL,DummyBuffer,sizeof(DummyBuffer)))
  4202.             {
  4203.                 FreeAslRequest(FileRequest);
  4204.  
  4205.                 if(GetFileSize(DummyBuffer))
  4206.                 {
  4207.                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  4208.                     {
  4209.                         if(Lines)
  4210.                         {
  4211.                             switch(ShowRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  4212.                             {
  4213.                                 case 0:
  4214.  
  4215.                                     Close(SomeFile);
  4216.                                     SomeFile = NULL;
  4217.                                     break;
  4218.  
  4219.                                 case 1:
  4220.  
  4221.                                     FreeBuffer();
  4222.                                     break;
  4223.                             }
  4224.                         }
  4225.  
  4226.                         if(SomeFile)
  4227.                         {
  4228.                             LONG Len;
  4229.  
  4230.                             LineRead(NULL,NULL,NULL);
  4231.  
  4232.                             while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
  4233.                                 CaptureParser(ParserStuff,DummyBuffer,Len,(COPTR)AddLine);
  4234.  
  4235.                             Close(SomeFile);
  4236.  
  4237.                             BufferChanged = TRUE;
  4238.                         }
  4239.                     }
  4240.                     else
  4241.                         ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  4242.                 }
  4243.             }
  4244.  
  4245.             ReleaseWindows();
  4246.             break;
  4247.  
  4248.             /* Save the contents of the scrollback
  4249.              * buffer to a file (line by line).
  4250.              */
  4251.  
  4252.         case MEN_SAVE_BUFFER_AS:
  4253.  
  4254.             BlockWindows();
  4255.  
  4256.             if(!Lines || !BufferLines)
  4257.                 ShowRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4258.             else
  4259.             {
  4260.                 DummyBuffer[0] = 0;
  4261.  
  4262.                 if(FileRequest = SaveFileOverwrite(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),NULL,NULL,DummyBuffer,sizeof(DummyBuffer)))
  4263.                 {
  4264.                     LONG Error = 0;
  4265.  
  4266.                     FreeAslRequest(FileRequest);
  4267.  
  4268.                     SomeFile = NULL;
  4269.  
  4270.                         /* If the file we are about
  4271.                          * to create already exists,
  4272.                          * ask the user whether we are
  4273.                          * to create, append or skip
  4274.                          * the file.
  4275.                          */
  4276.  
  4277.                     if(GetFileSize(DummyBuffer))
  4278.                     {
  4279.                         switch(ShowRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  4280.                         {
  4281.                             case 1:
  4282.  
  4283.                                 SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  4284.                                 break;
  4285.  
  4286.                             case 2:
  4287.  
  4288.                                 SomeFile = OpenToAppend(DummyBuffer,NULL);
  4289.                                 break;
  4290.                         }
  4291.                     }
  4292.                     else
  4293.                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  4294.  
  4295.                     if(SomeFile)
  4296.                     {
  4297.                         LONG i,Len;
  4298.  
  4299.                             /* Obtain the semaphore required
  4300.                              * to gain access to the line buffer
  4301.                              */
  4302.  
  4303.                         SafeObtainSemaphoreShared(&BufferSemaphore);
  4304.  
  4305.                         for(i = 0 ; i < Lines ; i++)
  4306.                         {
  4307.                             Len = BufferLines[i][-1];
  4308.  
  4309.                             if(Len)
  4310.                             {
  4311.                                 SetIoErr(0);
  4312.  
  4313.                                 if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
  4314.                                 {
  4315.                                     Error = IoErr();
  4316.  
  4317.                                     break;
  4318.                                 }
  4319.                             }
  4320.  
  4321.                             SetIoErr(0);
  4322.  
  4323.                             if(FPrintf(SomeFile,"\n") < 1)
  4324.                             {
  4325.                                 Error = IoErr();
  4326.  
  4327.                                 break;
  4328.                             }
  4329.                         }
  4330.  
  4331.                         ReleaseSemaphore(&BufferSemaphore);
  4332.  
  4333.                         Close(SomeFile);
  4334.  
  4335.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  4336.  
  4337.                         if(Config->MiscConfig->CreateIcons)
  4338.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  4339.  
  4340.                         BufferChanged = FALSE;
  4341.                     }
  4342.                     else
  4343.                         Error = IoErr();
  4344.  
  4345.                     if(Error)
  4346.                         ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  4347.                 }
  4348.             }
  4349.  
  4350.             ReleaseWindows();
  4351.  
  4352.             break;
  4353.  
  4354.             /* Simply clear the screen and move the
  4355.              * cursor to its home position.
  4356.              */
  4357.  
  4358.         case MEN_CLEAR_SCREEN:
  4359.  
  4360.             ConClear();
  4361.             break;
  4362.  
  4363.             /* Reset the current text rendering font. */
  4364.  
  4365.         case MEN_RESET_FONT:
  4366.  
  4367.             ConResetFont();
  4368.             break;
  4369.  
  4370.             /* Reset the display styles and restore
  4371.              * the colours.
  4372.              */
  4373.  
  4374.         case MEN_RESET_STYLES:
  4375.  
  4376.             ConResetStyles();
  4377.             break;
  4378.  
  4379.             /* Reset the whole terminal. */
  4380.  
  4381.         case MEN_RESET_TERMINAL:
  4382.  
  4383.             ConResetTerminal();
  4384.             break;
  4385.  
  4386.         case MEN_SET_EMULATION:
  4387.  
  4388.             BlockWindows();
  4389.  
  4390.             if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  4391.             {
  4392.                 OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  4393.  
  4394.                 NewOptions = FALSE;
  4395.  
  4396.                 XEmulatorOptions(XEM_IO);
  4397.  
  4398.                 if(NewOptions)
  4399.                 {
  4400.                     SetEmulatorOptions(XEM_PREFS_SAVE);
  4401.  
  4402.                     NewOptions = FALSE;
  4403.                 }
  4404.  
  4405.                 OptionTitle = NULL;
  4406.             }
  4407.             else
  4408.             {
  4409.                 if(EmulationPanel(Window,Config))
  4410.                 {
  4411.                     ConfigSetup();
  4412.  
  4413.                     ConfigChanged = TRUE;
  4414.                 }
  4415.             }
  4416.  
  4417.             ReleaseWindows();
  4418.  
  4419.             break;
  4420.  
  4421.             /* Set the serial preferences. */
  4422.  
  4423.         case MEN_SERIAL:
  4424.  
  4425.             BlockWindows();
  4426.  
  4427.             if(SerialPanel(Window,Config))
  4428.             {
  4429.                 ConfigSetup();
  4430.  
  4431.                 ConfigChanged = TRUE;
  4432.             }
  4433.  
  4434.             ReleaseWindows();
  4435.  
  4436.             break;
  4437.  
  4438.             /* Set the modem preferences. */
  4439.  
  4440.         case MEN_MODEM:
  4441.  
  4442.             BlockWindows();
  4443.  
  4444.             if(ModemPanel(Window,Config))
  4445.             {
  4446.                 ResetDataFlowFilter();
  4447.  
  4448.                 ConfigChanged = TRUE;
  4449.             }
  4450.  
  4451.             ReleaseWindows();
  4452.  
  4453.             break;
  4454.  
  4455.             /* Set the screen preferences. */
  4456.  
  4457.         case MEN_SCREEN:
  4458.  
  4459.             BlockWindows();
  4460.  
  4461.             if(ScreenPanel(Window,Config))
  4462.             {
  4463.                 if(memcmp(PrivateConfig->ScreenConfig->Colours,Config->ScreenConfig->Colours,sizeof(UWORD) * 16))
  4464.                 {
  4465.                     switch(Config->ScreenConfig->ColourMode)
  4466.                     {
  4467.                         case COLOUR_EIGHT:
  4468.  
  4469.                             CopyMem(Config->ScreenConfig->Colours,ANSIColours,16 * sizeof(UWORD));
  4470.                             break;
  4471.  
  4472.                         case COLOUR_SIXTEEN:
  4473.  
  4474.                             CopyMem(Config->ScreenConfig->Colours,EGAColours,16 * sizeof(UWORD));
  4475.                             break;
  4476.  
  4477.                         case COLOUR_AMIGA:
  4478.  
  4479.                             CopyMem(Config->ScreenConfig->Colours,DefaultColours,16 * sizeof(UWORD));
  4480.                             break;
  4481.  
  4482.                         case COLOUR_MONO:
  4483.  
  4484.                             CopyMem(Config->ScreenConfig->Colours,AtomicColours,16 * sizeof(UWORD));
  4485.                             break;
  4486.                     }
  4487.                 }
  4488.  
  4489.                 ConfigSetup();
  4490.  
  4491.                 ConfigChanged = TRUE;
  4492.             }
  4493.             else
  4494.             {
  4495.                 if(memcmp(PrivateConfig->ScreenConfig->Colours,Config->ScreenConfig->Colours,sizeof(UWORD) * 16))
  4496.                 {
  4497.                     switch(Config->ScreenConfig->ColourMode)
  4498.                     {
  4499.                         case COLOUR_EIGHT:
  4500.  
  4501.                             CopyMem(Config->ScreenConfig->Colours,ANSIColours,16 * sizeof(UWORD));
  4502.                             break;
  4503.  
  4504.                         case COLOUR_SIXTEEN:
  4505.  
  4506.                             CopyMem(Config->ScreenConfig->Colours,EGAColours,16 * sizeof(UWORD));
  4507.                             break;
  4508.  
  4509.                         case COLOUR_AMIGA:
  4510.  
  4511.                             CopyMem(Config->ScreenConfig->Colours,DefaultColours,16 * sizeof(UWORD));
  4512.                             break;
  4513.  
  4514.                         case COLOUR_MONO:
  4515.  
  4516.                             CopyMem(Config->ScreenConfig->Colours,AtomicColours,16 * sizeof(UWORD));
  4517.                             break;
  4518.                     }
  4519.  
  4520.                     ConfigChanged = TRUE;
  4521.                 }
  4522.             }
  4523.  
  4524.             ReleaseWindows();
  4525.  
  4526.             break;
  4527.  
  4528.             /* Set the terminal preferences. */
  4529.  
  4530.         case MEN_TERMINAL:
  4531.  
  4532.             BlockWindows();
  4533.  
  4534.             if(!TerminalPanel(Window,Config))
  4535.                 ReleaseWindows();
  4536.             else
  4537.             {
  4538.                 ReleaseWindows();
  4539.  
  4540.                 Update_CR_LF_Translation();
  4541.  
  4542.                 ConfigSetup();
  4543.  
  4544.                 ConfigChanged = TRUE;
  4545.  
  4546.                     /* Make the changes now */
  4547.  
  4548.                 if(FixScreenSize && !ResetDisplay)
  4549.                 {
  4550.                     ScreenSizeStuff();
  4551.  
  4552.                     ForceStatusUpdate();
  4553.  
  4554.                     HandleMenuCode(NULL,MEN_RESET_TERMINAL,0);
  4555.                 }
  4556.             }
  4557.  
  4558.             break;
  4559.  
  4560.             /* Set the clipboard preferences. */
  4561.  
  4562.         case MEN_CLIPBOARD:
  4563.  
  4564.             BlockWindows();
  4565.  
  4566.             if(ClipPanel(Window,Config))
  4567.             {
  4568.                 ConfigSetup();
  4569.  
  4570.                 ConfigChanged = TRUE;
  4571.             }
  4572.  
  4573.             ReleaseWindows();
  4574.  
  4575.             break;
  4576.  
  4577.             /* Set the capture preferences. */
  4578.  
  4579.         case MEN_CAPTURE:
  4580.  
  4581.             BlockWindows();
  4582.  
  4583.             if(CapturePanel(Window,Config))
  4584.             {
  4585.                 ConOutputUpdate();
  4586.  
  4587.                 ConfigSetup();
  4588.  
  4589.                 ConfigChanged = TRUE;
  4590.             }
  4591.  
  4592.             ReleaseWindows();
  4593.  
  4594.             break;
  4595.  
  4596.             /* Set the command preferences. */
  4597.  
  4598.         case MEN_COMMANDS:
  4599.  
  4600.             BlockWindows();
  4601.  
  4602.             if(CommandPanel(Window,Config))
  4603.                 ConfigChanged = TRUE;
  4604.  
  4605.             ReleaseWindows();
  4606.  
  4607.             break;
  4608.  
  4609.             /* Set the miscellaneous preferences. */
  4610.  
  4611.         case MEN_MISC:
  4612.  
  4613.             BlockWindows();
  4614.  
  4615.             if(MiscPanel(Window,Config))
  4616.             {
  4617.                 ConfigSetup();
  4618.  
  4619.                 ConfigChanged = TRUE;
  4620.             }
  4621.  
  4622.             ReleaseWindows();
  4623.  
  4624.             break;
  4625.  
  4626.             /* Set the path settings. */
  4627.  
  4628.         case MEN_PATH:
  4629.  
  4630.             BlockWindows();
  4631.  
  4632.             if(PathPanel(Window,Config))
  4633.                 ConfigChanged = TRUE;
  4634.  
  4635.             ReleaseWindows();
  4636.  
  4637.             break;
  4638.  
  4639.             /* Set the file transfer options. */
  4640.  
  4641.         case MEN_TRANSFER:
  4642.  
  4643.             BlockWindows();
  4644.  
  4645. #ifdef BUILTIN_ZMODEM
  4646.             if(UseInternalZModem)
  4647.             {
  4648.                 ZSettings();
  4649.  
  4650.                 ReleaseWindows();
  4651.  
  4652.                 break;
  4653.             }
  4654. #endif    /* BUILTIN_ZMODEM */
  4655.  
  4656.             XprIO->xpr_filename = NULL;
  4657.  
  4658.                 /* Set up the library options. */
  4659.  
  4660.             if(XProtocolBase)
  4661.             {
  4662.                 XPRCommandSelected = FALSE;
  4663.  
  4664.                 ClearSerial();
  4665.  
  4666.                 NewOptions = FALSE;
  4667.  
  4668.                 TransferBits = XProtocolSetup(XprIO);
  4669.  
  4670.                 RestartSerial();
  4671.  
  4672.                 DeleteTransferPanel(TRUE);
  4673.  
  4674.                     /* Successful? */
  4675.  
  4676.                 if(!(TransferBits & XPRS_SUCCESS))
  4677.                 {
  4678.                     ShowRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  4679.  
  4680.                     CloseLibrary(XProtocolBase);
  4681.  
  4682.                     XProtocolBase = NULL;
  4683.  
  4684.                     LastXprLibrary[0] = 0;
  4685.  
  4686.                     TransferBits = 0;
  4687.  
  4688.                     SetTransferMenu(TRUE);
  4689.                 }
  4690.                 else
  4691.                     SaveProtocolOpts();
  4692.             }
  4693.  
  4694.             ReleaseWindows();
  4695.  
  4696.             break;
  4697.  
  4698.             /* Set the file transfer procol settings. */
  4699.  
  4700.         case MEN_TRANSFER_PROTOCOL:
  4701.  
  4702.             BlockWindows();
  4703.  
  4704.             if(LibPanel(Window,Config))
  4705.             {
  4706.                 ConfigSetup();
  4707.  
  4708.                 ConfigChanged = TRUE;
  4709.  
  4710.                 ResetDataFlowFilter();
  4711.             }
  4712.  
  4713.             ReleaseWindows();
  4714.  
  4715.             break;
  4716.  
  4717.             /* Set the translation tables. */
  4718.  
  4719.         case MEN_TRANSLATION:
  4720.  
  4721.             BlockWindows();
  4722.  
  4723.             TranslationPanelConfig(Config,&SendTable,&ReceiveTable,LastTranslation,Window,&TranslationChanged);
  4724.  
  4725.                 /* Choose the right console write routine. */
  4726.  
  4727.             ConOutputUpdate();
  4728.  
  4729.             ReleaseWindows();
  4730.  
  4731.             break;
  4732.  
  4733.             /* Set the keyboard macros. */
  4734.  
  4735.         case MEN_MACROS:
  4736.  
  4737.             BlockWindows();
  4738.  
  4739.             if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  4740.             {
  4741.                 XEmulatorMacroKeyFilter(XEM_IO,NULL);
  4742.  
  4743.                 MacroPanelConfig(Config,MacroKeys,LastMacros,Window,&MacroChanged);
  4744.  
  4745.                 SetupXEM_MacroKeys(MacroKeys);
  4746.             }
  4747.             else
  4748.                 MacroPanelConfig(Config,MacroKeys,LastMacros,Window,&MacroChanged);
  4749.  
  4750.             ReleaseWindows();
  4751.  
  4752.             break;
  4753.  
  4754.             /* Set the cursor keys. */
  4755.  
  4756.         case MEN_CURSORKEYS:
  4757.  
  4758.             BlockWindows();
  4759.  
  4760.             CursorPanelConfig(Config,CursorKeys,LastCursorKeys,Window,&CursorKeysChanged);
  4761.  
  4762.             ReleaseWindows();
  4763.  
  4764.             break;
  4765.  
  4766.             /* Set the fast macros. */
  4767.  
  4768.         case MEN_FAST_MACROS:
  4769.  
  4770.             BlockWindows();
  4771.  
  4772.             if(FastMacroPanelConfig(Config,&FastMacroList,LastFastMacros,Window,&FastMacrosChanged))
  4773.             {
  4774.                 FastMacroCount = GetListSize(&FastMacroList);
  4775.                 RefreshFastWindow();
  4776.             }
  4777.  
  4778.             ReleaseWindows();
  4779.  
  4780.             break;
  4781.  
  4782.             /* Set the hotkey preferences. */
  4783.  
  4784.         case MEN_HOTKEYS:
  4785.  
  4786.             BlockWindows();
  4787.  
  4788.             if(HotkeyPanelConfig(Config,&Hotkeys,LastKeys,&HotkeysChanged))
  4789.             {
  4790.                 if(LastKeys[0] && !SetupCx())
  4791.                     ShowRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4792.             }
  4793.  
  4794.             ReleaseWindows();
  4795.  
  4796.             break;
  4797.  
  4798.             /* Set the speech preferences. */
  4799.  
  4800.         case MEN_SPEECH:
  4801.  
  4802.             BlockWindows();
  4803.  
  4804.             SpeechPanelConfig(&SpeechConfig,LastSpeech,&SpeechChanged);
  4805.  
  4806.             ReleaseWindows();
  4807.  
  4808.             break;
  4809.  
  4810.             /* Set the sound preferences. */
  4811.  
  4812.         case MEN_SOUND:
  4813.  
  4814.             BlockWindows();
  4815.  
  4816.             if(SoundPanelConfig(&SoundConfig,LastSound,&SoundChanged))
  4817.             {
  4818.                 if(LastSound[0])
  4819.                     SoundInit();
  4820.             }
  4821.  
  4822.             ReleaseWindows();
  4823.  
  4824.             break;
  4825.  
  4826.             /* Edit the phone number patterns and rates. */
  4827.  
  4828.         case MEN_RATES:
  4829.  
  4830.             BlockWindows();
  4831.  
  4832.             PatternPanelConfig(PatternList,LastPattern,&PatternsChanged);
  4833.  
  4834.             ReleaseWindows();
  4835.  
  4836.             break;
  4837.  
  4838.             /* Open the preferences settings. */
  4839.  
  4840.         case MEN_OPEN_SETTINGS:
  4841.  
  4842.             BlockWindows();
  4843.  
  4844.             strcpy(DummyBuffer,LastConfig);
  4845.  
  4846.             if(FileRequest = OpenSingleFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),NULL,"#?.prefs",DummyBuffer,sizeof(DummyBuffer)))
  4847.             {
  4848.                 FreeAslRequest(FileRequest);
  4849.  
  4850.                 if(ReadConfig(DummyBuffer,PrivateConfig))
  4851.                 {
  4852.                     SwapConfig(PrivateConfig,Config);
  4853.  
  4854.                     strcpy(LastConfig,DummyBuffer);
  4855.  
  4856.                     ConfigSetup();
  4857.  
  4858.                     ConfigChanged = FALSE;
  4859.                 }
  4860.                 else
  4861.                     ShowRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  4862.             }
  4863.  
  4864.             ReleaseWindows();
  4865.  
  4866.             break;
  4867.  
  4868.             /* Save the terminal preferences. */
  4869.  
  4870.         case MEN_SAVE_SETTINGS:
  4871.  
  4872.             if(LastConfig[0])
  4873.             {
  4874.                 BlockWindows();
  4875.  
  4876.                 if(!Screen)
  4877.                     PutWindowInfo(WINDOW_MAIN,Window->LeftEdge,Window->TopEdge,Window->Width,Window->Height);
  4878.  
  4879.                 if(!WriteConfig(LastConfig,Config))
  4880.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
  4881.                 else
  4882.                     ConfigChanged = FALSE;
  4883.  
  4884.                 ReleaseWindows();
  4885.  
  4886.                 break;
  4887.             }
  4888.  
  4889.             /* Save the terminal preferences to a
  4890.              * given file name.
  4891.              */
  4892.  
  4893.         case MEN_SAVE_SETTINGS_AS:
  4894.  
  4895.             BlockWindows();
  4896.  
  4897.             strcpy(DummyBuffer,LastConfig);
  4898.  
  4899.             if(FileRequest = SaveFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),NULL,"#?.prefs",DummyBuffer,sizeof(DummyBuffer)))
  4900.             {
  4901.                 FreeAslRequest(FileRequest);
  4902.  
  4903.                 if(!Screen)
  4904.                     PutWindowInfo(WINDOW_MAIN,Window->LeftEdge,Window->TopEdge,Window->Width,Window->Height);
  4905.  
  4906.                 if(WriteConfig(DummyBuffer,Config))
  4907.                 {
  4908.                     strcpy(LastConfig,DummyBuffer);
  4909.  
  4910.                     ConfigChanged = FALSE;
  4911.                 }
  4912.                 else
  4913.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  4914.             }
  4915.  
  4916.             ReleaseWindows();
  4917.  
  4918.             break;
  4919.  
  4920.             /* Show terminal information window. */
  4921.  
  4922.         case MEN_STATUS_WINDOW:
  4923.  
  4924.             if(InfoWindow)
  4925.                 CloseInfoWindow();
  4926.             else
  4927.                 OpenInfoWindow();
  4928.  
  4929.             break;
  4930.  
  4931.         case MEN_REVIEW_WINDOW:
  4932.  
  4933.             if(ReviewWindow)
  4934.                 DeleteReview();
  4935.             else
  4936.                 CreateReview();
  4937.  
  4938.             break;
  4939.  
  4940.         case MEN_MATRIX_WINDOW:
  4941.  
  4942.             if(MatrixWindow)
  4943.                 CloseMatrixWindow();
  4944.             else
  4945.                 OpenMatrixWindow(Window);
  4946.  
  4947.             break;
  4948.  
  4949.             /* Open the packet window if necessary, else
  4950.              * just activate it.
  4951.              */
  4952.  
  4953.         case MEN_PACKET_WINDOW:
  4954.  
  4955.             CreatePacketWindow();
  4956.             break;
  4957.  
  4958.             /* Enable or disable the packet window */
  4959.  
  4960.         case MEN_CHAT_LINE:
  4961.  
  4962.             Checked = GetItem(MEN_CHAT_LINE);
  4963.  
  4964.             if(Checked != ChatMode)
  4965.             {
  4966.                 ChatMode = Checked;
  4967.  
  4968.                 ResetDisplay = TRUE;
  4969.                 ActivateJob(MainJobQueue,ResetDisplayJob);
  4970.             }
  4971.  
  4972.             break;
  4973.  
  4974.             /* Toggle the presence of the fast! macro panel. */
  4975.  
  4976.         case MEN_FAST_MACROS_WINDOW:
  4977.  
  4978.             if(FastWindow)
  4979.                 CloseFastWindow();
  4980.             else
  4981.                 OpenFastWindow();
  4982.  
  4983.             break;
  4984.  
  4985.             /* Open the upload queue window. */
  4986.  
  4987.         case MEN_UPLOAD_QUEUE_WINDOW:
  4988.  
  4989.             CreateQueueProcess();
  4990.             break;
  4991.  
  4992.             /* Check if we should go for the quick dial menu */
  4993.  
  4994.         default:
  4995.  
  4996.             if(Code >= DIAL_MENU_LIMIT && ThisItem != NULL)
  4997.             {
  4998.                 LONG i;
  4999.  
  5000.                 if(ThisItem->Flags & CHECKED)
  5001.                 {
  5002.                     if(QuickDialMax < DIAL_MENU_MAX)
  5003.                     {
  5004.                         LONG Which;
  5005.  
  5006.                         Which = -1;
  5007.  
  5008.                         for(i = 0 ; i < QuickDialMax ; i++)
  5009.                         {
  5010.                             if(QuickDialTable[i] == Code)
  5011.                             {
  5012.                                 Which = i;
  5013.                                 break;
  5014.                             }
  5015.                             else
  5016.                             {
  5017.                                 if(QuickDialTable[i] == -1)
  5018.                                     Which = i;
  5019.                             }
  5020.                         }
  5021.  
  5022.                         if(Which == -1)
  5023.                             Which = QuickDialMax++;
  5024.  
  5025.                         QuickDialTable[Which] = Code;
  5026.                     }
  5027.                 }
  5028.                 else
  5029.                 {
  5030.                     for(i = 0 ; i < QuickDialMax ; i++)
  5031.                     {
  5032.                         if(QuickDialTable[i] == Code)
  5033.                             QuickDialTable[i] = -1;
  5034.                     }
  5035.  
  5036.                     for(i = QuickDialMax - 1 ; i >= 0 ; i--)
  5037.                     {
  5038.                         if(QuickDialTable[i] == -1)
  5039.                             QuickDialMax = i;
  5040.                         else
  5041.                             break;
  5042.                     }
  5043.                 }
  5044.  
  5045.                 CheckDialMenu = TRUE;
  5046.             }
  5047.  
  5048.             break;
  5049.     }
  5050. }
  5051.  
  5052.     /* HandleReleaseSerial():
  5053.      *
  5054.      *    Release the serial device driver, then reopen it again.
  5055.      */
  5056.  
  5057. BOOL
  5058. HandleReleaseSerial(JobNode *UnusedJob)
  5059. {
  5060.     if(!MainTerminated)
  5061.         LocalReleaseSerial();
  5062.  
  5063.     return(FALSE);
  5064. }
  5065.  
  5066.     /* HandleStartupFile(JobNode *Job):
  5067.      *
  5068.      *    Launches the startup ARexx script.
  5069.      */
  5070.  
  5071. BOOL
  5072. HandleStartupFile(JobNode *UnusedJob)
  5073. {
  5074.     if(!MainTerminated)
  5075.     {
  5076.         LaunchRexxAsync(StartupFile);
  5077.  
  5078.         StartupFile[0] = 0;
  5079.     }
  5080.  
  5081.     return(FALSE);
  5082. }
  5083.  
  5084. BOOL
  5085. HandleIconifyJob(JobNode *UnusedJob)
  5086. {
  5087.     if(!MainTerminated)
  5088.         HandleIconify();
  5089.  
  5090.     return(FALSE);
  5091. }
  5092.  
  5093. BOOL
  5094. HandleRebuildMenuJob(JobNode *UnusedJob)
  5095. {
  5096.     if(!ResetDisplay && !MainTerminated)
  5097.     {
  5098.         struct Menu *Menu;
  5099.  
  5100.         if(Menu = BuildMenu())
  5101.             AttachMenu(Menu);
  5102.         else
  5103.             DisconnectDialMenu();
  5104.  
  5105.         RebuildMenu = FALSE;
  5106.     }
  5107.  
  5108.     return(FALSE);
  5109. }
  5110.  
  5111. BOOL
  5112. HandleResetDisplayJob(JobNode *UnusedJob)
  5113. {
  5114.     if(!MainTerminated)
  5115.     {
  5116.         if(!DisplayReset())
  5117.             MainTerminated = TRUE;
  5118.     }
  5119.  
  5120.     return(FALSE);
  5121. }
  5122.  
  5123. BOOL
  5124. HandleOnlineCleanupJob(JobNode *UnusedJob)
  5125. {
  5126.     if(!MainTerminated)
  5127.     {
  5128.         HandleOnlineCleanup(HungUp);
  5129.  
  5130.         WasOnline    = FALSE;
  5131.         HungUp        = FALSE;
  5132.     }
  5133.  
  5134.     return(FALSE);
  5135. }
  5136.  
  5137. BOOL
  5138. HandleDisplayCostJob(JobNode *Job)
  5139. {
  5140.     BOOL TurnOff = TRUE;
  5141.  
  5142.     if(!MainTerminated)
  5143.     {
  5144.         if(ResetDisplay)
  5145.             TurnOff = FALSE;
  5146.         else
  5147.         {
  5148.             UBYTE Sum[20];
  5149.             LONG ID;
  5150.  
  5151.                 /* Reset the text rendering styles, font, etc. in
  5152.                  * order to keep the following text from getting
  5153.                  * illegible.
  5154.                  */
  5155.  
  5156.             SoftReset();
  5157.  
  5158.             if(DisplayPay)
  5159.             {
  5160.                 if(DisplayHangup)
  5161.                     ID = MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT;
  5162.                 else
  5163.                     ID = MSG_TERMAUX_CARRIER_LOST_COST_TXT;
  5164.  
  5165.                 CreateSum((DisplayPay + 5000) / 10000,TRUE,Sum,sizeof(Sum));
  5166.  
  5167.                     /* Display how much we expect
  5168.                      * the user will have to pay for
  5169.                      * this call.
  5170.                      */
  5171.  
  5172.                 ConPrintf(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),Sum);
  5173.             }
  5174.             else
  5175.             {
  5176.                 if(DisplayHangup)
  5177.                     ID = MSG_TERMMAIN_LOGMSG_HANG_UP_TXT;
  5178.                 else
  5179.                     ID = MSG_TERMAUX_CARRIER_LOST_TXT;
  5180.  
  5181.                 Sum[0] = 0;
  5182.             }
  5183.  
  5184.             LogAction(LocaleString(ID),Sum);
  5185.  
  5186.             DisplayHangup    = FALSE;
  5187.             DisplayPay        = 0;
  5188.         }
  5189.     }
  5190.  
  5191.     if(TurnOff)
  5192.         SuspendJob(MainJobQueue,Job);
  5193.  
  5194.     return(FALSE);
  5195. }
  5196.